Changeset 89c57b6 in mainline for uspace/srv/net/tl/tcp/tcp.c
- Timestamp:
- 2011-04-13T14:45:41Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 88634420
- Parents:
- cefb126 (diff), 17279ead (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
rcefb126 r89c57b6 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 37 … … 40 40 #include <fibril_synch.h> 41 41 #include <malloc.h> 42 / /TODO remove stdio42 /* TODO remove stdio */ 43 43 #include <stdio.h> 44 45 #include <ipc/ipc.h> 44 #include <errno.h> 45 46 46 #include <ipc/services.h> 47 48 #include <net_err.h> 49 #include <net_messages.h> 50 #include <net_modules.h> 47 #include <ipc/net.h> 48 #include <ipc/tl.h> 49 #include <ipc/socket.h> 50 51 #include <net/socket_codes.h> 52 #include <net/ip_protocols.h> 53 #include <net/in.h> 54 #include <net/in6.h> 55 #include <net/inet.h> 56 #include <net/modules.h> 57 51 58 #include <adt/dynamic_fifo.h> 52 #include <packet /packet_client.h>59 #include <packet_client.h> 53 60 #include <packet_remote.h> 54 61 #include <net_checksum.h> 55 #include <in.h>56 #include <in6.h>57 #include <inet.h>58 62 #include <ip_client.h> 59 63 #include <ip_interface.h> 60 #include <ip_protocols.h>61 64 #include <icmp_client.h> 62 #include <icmp_ interface.h>65 #include <icmp_remote.h> 63 66 #include <net_interface.h> 64 #include <socket_codes.h>65 #include <socket_errno.h>66 #include <tcp_codes.h>67 67 #include <socket_core.h> 68 #include <socket_messages.h>69 68 #include <tl_common.h> 70 #include <tl_messages.h> 71 #include <tl_local.h> 72 #include <tl_interface.h> 69 #include <tl_remote.h> 70 #include <tl_skel.h> 73 71 74 72 #include "tcp.h" 75 73 #include "tcp_header.h" 76 #include "tcp_module.h" 77 78 /** TCP module name. 74 75 /** TCP module name. */ 76 #define NAME "tcp" 77 78 /** The TCP window default value. */ 79 #define NET_DEFAULT_TCP_WINDOW 10240 80 81 /** Initial timeout for new connections. */ 82 #define NET_DEFAULT_TCP_INITIAL_TIMEOUT 3000000L 83 84 /** Default timeout for closing. */ 85 #define NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT 2000L 86 87 /** The initial outgoing sequence number. */ 88 #define TCP_INITIAL_SEQUENCE_NUMBER 2999 89 90 /** Maximum TCP fragment size. */ 91 #define MAX_TCP_FRAGMENT_SIZE 65535 92 93 /** Free ports pool start. */ 94 #define TCP_FREE_PORTS_START 1025 95 96 /** Free ports pool end. */ 97 #define TCP_FREE_PORTS_END 65535 98 99 /** Timeout for connection initialization, SYN sent. */ 100 #define TCP_SYN_SENT_TIMEOUT 1000000L 101 102 /** The maximum number of timeouts in a row before singaling connection lost. */ 103 #define TCP_MAX_TIMEOUTS 8 104 105 /** The number of acknowledgements before retransmit. */ 106 #define TCP_FAST_RETRANSMIT_COUNT 3 107 108 /** Returns a value indicating whether the value is in the interval respecting 109 * the possible overflow. 110 * 111 * The high end and/or the value may overflow, be lower than the low value. 112 * 113 * @param[in] lower The last value before the interval. 114 * @param[in] value The value to be checked. 115 * @param[in] higher_equal The last value in the interval. 79 116 */ 80 #define NAME "TCP protocol" 81 82 /** The TCP window default value. 83 */ 84 #define NET_DEFAULT_TCP_WINDOW 10240 85 86 /** Initial timeout for new connections. 87 */ 88 #define NET_DEFAULT_TCP_INITIAL_TIMEOUT 3000000L 89 90 /** Default timeout for closing. 91 */ 92 #define NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT 2000L 93 94 /** The initial outgoing sequence number. 95 */ 96 #define TCP_INITIAL_SEQUENCE_NUMBER 2999 97 98 /** Maximum TCP fragment size. 99 */ 100 #define MAX_TCP_FRAGMENT_SIZE 65535 101 102 /** Free ports pool start. 103 */ 104 #define TCP_FREE_PORTS_START 1025 105 106 /** Free ports pool end. 107 */ 108 #define TCP_FREE_PORTS_END 65535 109 110 /** Timeout for connection initialization, SYN sent. 111 */ 112 #define TCP_SYN_SENT_TIMEOUT 1000000L 113 114 /** The maximum number of timeouts in a row before singaling connection lost. 115 */ 116 #define TCP_MAX_TIMEOUTS 8 117 118 /** The number of acknowledgements before retransmit. 119 */ 120 #define TCP_FAST_RETRANSMIT_COUNT 3 121 122 /** Returns a value indicating whether the value is in the interval respecting the possible overflow. 123 * The high end and/or the value may overflow, be lower than the low value. 124 * @param[in] lower The last value before the interval. 125 * @param[in] value The value to be checked. 126 * @param[in] higher_equal The last value in the interval. 127 */ 128 #define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) ((((lower) < (value)) && (((value) <= (higher_equal)) || ((higher_equal) < (lower)))) || (((value) <= (higher_equal)) && ((higher_equal) < (lower)))) 117 #define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \ 118 ((((lower) < (value)) && (((value) <= (higher_equal)) || \ 119 ((higher_equal) < (lower)))) || (((value) <= (higher_equal)) && \ 120 ((higher_equal) < (lower)))) 129 121 130 122 /** Type definition of the TCP timeout. 131 123 * @see tcp_timeout 132 124 */ 133 typedef struct tcp_timeout tcp_timeout_t; 134 135 /** Type definition of the TCP timeout pointer. 136 * @see tcp_timeout 137 */ 138 typedef tcp_timeout_t * tcp_timeout_ref; 125 typedef struct tcp_timeout tcp_timeout_t; 139 126 140 127 /** TCP reply timeout data. … … 142 129 * @see tcp_timeout() 143 130 */ 144 struct tcp_timeout{ 145 /** TCP global data are going to be read only. 146 */ 131 struct tcp_timeout { 132 /** TCP global data are going to be read only. */ 147 133 int globals_read_only; 148 /** Socket port. 149 */134 135 /** Socket port. */ 150 136 int port; 151 /** Local sockets. 152 */153 socket_cores_ reflocal_sockets;154 /** Socket identifier. 155 */137 138 /** Local sockets. */ 139 socket_cores_t *local_sockets; 140 141 /** Socket identifier. */ 156 142 int socket_id; 157 /** Socket state. 158 */143 144 /** Socket state. */ 159 145 tcp_socket_state_t state; 160 /** Sent packet sequence number. 161 */146 147 /** Sent packet sequence number. */ 162 148 int sequence_number; 163 /** Timeout in microseconds. 164 */149 150 /** Timeout in microseconds. */ 165 151 suseconds_t timeout; 166 /** Port map key. 167 */168 char *key;169 /** Port map key length. 170 */152 153 /** Port map key. */ 154 uint8_t *key; 155 156 /** Port map key length. */ 171 157 size_t key_length; 172 158 }; 173 159 174 /** Releases the packet and returns the result. 175 * @param[in] packet The packet queue to be released. 176 * @param[in] result The result to be returned. 177 * @return The result parameter. 178 */ 179 int tcp_release_and_return(packet_t packet, int result); 180 181 void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize); 182 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); 183 void tcp_free_socket_data(socket_core_ref socket); 184 int tcp_timeout(void * data); 185 int tcp_release_after_timeout(void * data); 186 int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error); 187 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen); 188 int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length); 189 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length); 190 packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data); 191 void tcp_send_packets(device_id_t device_id, packet_t packet); 192 void tcp_process_acknowledgement(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header); 193 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); 194 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); 195 void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number); 196 int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize); 197 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data); 198 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data); 199 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); 200 int tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 201 int tcp_process_syn_received(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 202 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); 203 int tcp_queue_received_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length); 204 205 int tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error); 206 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 207 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog); 208 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen); 209 int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen); 210 int tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags); 211 int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen); 212 int tcp_close_message(socket_cores_ref local_sockets, int socket_id); 213 214 /** TCP global data. 215 */ 216 tcp_globals_t tcp_globals; 217 218 int tcp_initialize(async_client_conn_t client_connection){ 219 ERROR_DECLARE; 220 221 assert(client_connection); 222 fibril_rwlock_initialize(&tcp_globals.lock); 160 static int tcp_release_and_return(packet_t *, int); 161 static void tcp_prepare_operation_header(socket_core_t *, tcp_socket_data_t *, 162 tcp_header_t *, int synchronize, int); 163 static int tcp_prepare_timeout(int (*)(void *), socket_core_t *, 164 tcp_socket_data_t *, size_t, tcp_socket_state_t, suseconds_t, int); 165 static void tcp_free_socket_data(socket_core_t *); 166 167 static int tcp_timeout(void *); 168 169 static int tcp_release_after_timeout(void *); 170 171 static int tcp_process_packet(device_id_t, packet_t *, services_t); 172 static int tcp_connect_core(socket_core_t *, socket_cores_t *, 173 struct sockaddr *, socklen_t); 174 static int tcp_queue_prepare_packet(socket_core_t *, tcp_socket_data_t *, 175 packet_t *, size_t); 176 static int tcp_queue_packet(socket_core_t *, tcp_socket_data_t *, packet_t *, 177 size_t); 178 static packet_t *tcp_get_packets_to_send(socket_core_t *, tcp_socket_data_t *); 179 static void tcp_send_packets(device_id_t, packet_t *); 180 181 static void tcp_process_acknowledgement(socket_core_t *, tcp_socket_data_t *, 182 tcp_header_t *); 183 static packet_t *tcp_send_prepare_packet(socket_core_t *, tcp_socket_data_t *, 184 packet_t *, size_t, size_t); 185 static packet_t *tcp_prepare_copy(socket_core_t *, tcp_socket_data_t *, 186 packet_t *, size_t, size_t); 187 /* static */ void tcp_retransmit_packet(socket_core_t *, tcp_socket_data_t *, 188 size_t); 189 static int tcp_create_notification_packet(packet_t **, socket_core_t *, 190 tcp_socket_data_t *, int, int); 191 static void tcp_refresh_socket_data(tcp_socket_data_t *); 192 193 static void tcp_initialize_socket_data(tcp_socket_data_t *); 194 195 static int tcp_process_listen(socket_core_t *, tcp_socket_data_t *, 196 tcp_header_t *, packet_t *, struct sockaddr *, struct sockaddr *, size_t); 197 static int tcp_process_syn_sent(socket_core_t *, tcp_socket_data_t *, 198 tcp_header_t *, packet_t *); 199 static int tcp_process_syn_received(socket_core_t *, tcp_socket_data_t *, 200 tcp_header_t *, packet_t *); 201 static int tcp_process_established(socket_core_t *, tcp_socket_data_t *, 202 tcp_header_t *, packet_t *, int, size_t); 203 static int tcp_queue_received_packet(socket_core_t *, tcp_socket_data_t *, 204 packet_t *, int, size_t); 205 static void tcp_queue_received_end_of_data(socket_core_t *socket); 206 207 static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t); 208 static int tcp_process_client_messages(ipc_callid_t, ipc_call_t); 209 210 static int tcp_listen_message(socket_cores_t *, int, int); 211 static int tcp_connect_message(socket_cores_t *, int, struct sockaddr *, 212 socklen_t); 213 static int tcp_recvfrom_message(socket_cores_t *, int, int, size_t *); 214 static int tcp_send_message(socket_cores_t *, int, int, size_t *, int); 215 static int tcp_accept_message(socket_cores_t *, int, int, size_t *, size_t *); 216 static int tcp_close_message(socket_cores_t *, int); 217 218 /** TCP global data. */ 219 tcp_globals_t tcp_globals; 220 221 int tcp_received_msg(device_id_t device_id, packet_t *packet, 222 services_t receiver, services_t error) 223 { 224 int rc; 225 226 if (receiver != SERVICE_TCP) 227 return EREFUSED; 228 223 229 fibril_rwlock_write_lock(&tcp_globals.lock); 224 tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT); 225 tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, SERVICE_TCP, client_connection, tcp_received_msg); 226 if(tcp_globals.ip_phone < 0){ 227 return tcp_globals.ip_phone; 228 } 229 ERROR_PROPAGATE(socket_ports_initialize(&tcp_globals.sockets)); 230 if(ERROR_OCCURRED(packet_dimensions_initialize(&tcp_globals.dimensions))){ 231 socket_ports_destroy(&tcp_globals.sockets); 232 return ERROR_CODE; 233 } 234 tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1; 235 fibril_rwlock_write_unlock(&tcp_globals.lock); 236 return EOK; 237 } 238 239 int tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){ 240 ERROR_DECLARE; 241 242 if(receiver != SERVICE_TCP){ 243 return EREFUSED; 244 } 245 fibril_rwlock_write_lock(&tcp_globals.lock); 246 if(ERROR_OCCURRED(tcp_process_packet(device_id, packet, error))){ 230 rc = tcp_process_packet(device_id, packet, error); 231 if (rc != EOK) 247 232 fibril_rwlock_write_unlock(&tcp_globals.lock); 248 } 249 printf("receive %d \n", ERROR_CODE); 250 251 return ERROR_CODE; 252 } 253 254 int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error){ 255 ERROR_DECLARE; 256 233 234 printf("receive %d \n", rc); 235 236 return rc; 237 } 238 239 int tcp_process_packet(device_id_t device_id, packet_t *packet, services_t error) 240 { 257 241 size_t length; 258 242 size_t offset; 259 243 int result; 260 tcp_header_ refheader;261 socket_core_ refsocket;262 tcp_socket_data_ refsocket_data;263 packet_t next_packet;244 tcp_header_t *header; 245 socket_core_t *socket; 246 tcp_socket_data_t *socket_data; 247 packet_t *next_packet; 264 248 size_t total_length; 265 249 uint32_t checksum; … … 267 251 icmp_type_t type; 268 252 icmp_code_t code; 269 struct sockaddr * 270 struct sockaddr * 253 struct sockaddr *src; 254 struct sockaddr *dest; 271 255 size_t addrlen; 272 273 printf("p1 \n"); 274 if(error){ 275 switch(error){ 276 case SERVICE_ICMP: 277 // process error 278 result = icmp_client_process_packet(packet, &type, &code, NULL, NULL); 279 if(result < 0){ 280 return tcp_release_and_return(packet, result); 281 } 282 length = (size_t) result; 283 if(ERROR_OCCURRED(packet_trim(packet, length, 0))){ 284 return tcp_release_and_return(packet, ERROR_CODE); 285 } 286 break; 287 default: 288 return tcp_release_and_return(packet, ENOTSUP); 289 } 290 } 291 292 // TODO process received ipopts? 256 int rc; 257 258 switch (error) { 259 case SERVICE_NONE: 260 break; 261 case SERVICE_ICMP: 262 /* Process error */ 263 result = icmp_client_process_packet(packet, &type, &code, NULL, 264 NULL); 265 if (result < 0) 266 return tcp_release_and_return(packet, result); 267 268 length = (size_t) result; 269 rc = packet_trim(packet, length, 0); 270 if (rc != EOK) 271 return tcp_release_and_return(packet, rc); 272 break; 273 default: 274 return tcp_release_and_return(packet, ENOTSUP); 275 } 276 277 /* TODO process received ipopts? */ 293 278 result = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL); 294 // printf("ip len %d\n", result); 295 if(result < 0){ 279 if (result < 0) 296 280 return tcp_release_and_return(packet, result); 297 } 281 298 282 offset = (size_t) result; 299 283 300 284 length = packet_get_data_length(packet); 301 // printf("packet len %d\n", length); 302 if(length <= 0){ 285 if (length <= 0) 303 286 return tcp_release_and_return(packet, EINVAL); 304 } 305 if (length < TCP_HEADER_SIZE + offset){287 288 if (length < TCP_HEADER_SIZE + offset) 306 289 return tcp_release_and_return(packet, NO_DATA); 307 } 308 309 // trim all but TCP header 310 if(ERROR_OCCURRED(packet_trim(packet, offset, 0))){ 311 return tcp_release_and_return(packet, ERROR_CODE); 312 } 313 314 // get tcp header 315 header = (tcp_header_ref) packet_get_data(packet); 316 if(! header){ 290 291 /* Trim all but TCP header */ 292 rc = packet_trim(packet, offset, 0); 293 if (rc != EOK) 294 return tcp_release_and_return(packet, rc); 295 296 /* Get tcp header */ 297 header = (tcp_header_t *) packet_get_data(packet); 298 if (!header) 317 299 return tcp_release_and_return(packet, NO_DATA); 318 } 319 // printf("header len %d, port %d \n", TCP_HEADER_LENGTH(header), ntohs(header->destination_port)); 320 300 301 #if 0 302 printf("header len %d, port %d \n", TCP_HEADER_LENGTH(header), 303 ntohs(header->destination_port)); 304 #endif 321 305 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest); 322 if (result <= 0){306 if (result <= 0) 323 307 return tcp_release_and_return(packet, result); 324 } 308 325 309 addrlen = (size_t) result; 326 310 327 if(ERROR_OCCURRED(tl_set_address_port(src, addrlen, ntohs(header->source_port)))){ 328 return tcp_release_and_return(packet, ERROR_CODE); 329 } 330 331 // find the destination socket 332 socket = socket_port_find(&tcp_globals.sockets, ntohs(header->destination_port), (const char *) src, addrlen); 333 if(! socket){ 334 // printf("listening?\n"); 335 // find the listening destination socket 336 socket = socket_port_find(&tcp_globals.sockets, ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0); 337 if(! socket){ 338 if(tl_prepare_icmp_packet(tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error) == EOK){ 339 icmp_destination_unreachable_msg(tcp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet); 340 } 341 return EADDRNOTAVAIL; 342 } 343 } 311 rc = tl_set_address_port(src, addrlen, ntohs(header->source_port)); 312 if (rc != EOK) 313 return tcp_release_and_return(packet, rc); 314 315 /* Find the destination socket */ 316 socket = socket_port_find(&tcp_globals.sockets, 317 ntohs(header->destination_port), (uint8_t *) src, addrlen); 318 if (!socket) { 319 /* Find the listening destination socket */ 320 socket = socket_port_find(&tcp_globals.sockets, 321 ntohs(header->destination_port), 322 (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0); 323 } 324 325 if (!socket) { 326 if (tl_prepare_icmp_packet(tcp_globals.net_phone, 327 tcp_globals.icmp_phone, packet, error) == EOK) { 328 icmp_destination_unreachable_msg(tcp_globals.icmp_phone, 329 ICMP_PORT_UNREACH, 0, packet); 330 } 331 return EADDRNOTAVAIL; 332 } 333 344 334 printf("socket id %d\n", socket->socket_id); 345 socket_data = (tcp_socket_data_ ref) socket->specific_data;335 socket_data = (tcp_socket_data_t *) socket->specific_data; 346 336 assert(socket_data); 347 337 348 / / some data received, clear the timeout counter338 /* Some data received, clear the timeout counter */ 349 339 socket_data->timeout_count = 0; 350 340 351 / / count the received packet fragments341 /* Count the received packet fragments */ 352 342 next_packet = packet; 353 343 fragments = 0; 354 344 checksum = 0; 355 345 total_length = 0; 356 do {357 ++ fragments;346 do { 347 fragments++; 358 348 length = packet_get_data_length(next_packet); 359 if (length <= 0){349 if (length <= 0) 360 350 return tcp_release_and_return(packet, NO_DATA); 361 } 351 362 352 total_length += length; 363 // add partial checksum if set 364 if(! error){ 365 checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet)); 366 } 367 }while((next_packet = pq_next(next_packet))); 368 // printf("fragments %d of %d bytes\n", fragments, total_length); 369 370 // printf("lock?\n"); 353 354 /* Add partial checksum if set */ 355 if (!error) { 356 checksum = compute_checksum(checksum, 357 packet_get_data(packet), 358 packet_get_data_length(packet)); 359 } 360 361 } while ((next_packet = pq_next(next_packet))); 362 371 363 fibril_rwlock_write_lock(socket_data->local_lock); 372 // printf("locked\n"); 373 if(! error){ 374 if(socket_data->state == TCP_SOCKET_LISTEN){ 375 if(socket_data->pseudo_header){ 376 free(socket_data->pseudo_header); 377 socket_data->pseudo_header = NULL; 378 socket_data->headerlen = 0; 379 } 380 if(ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_TCP, src, addrlen, dest, addrlen, total_length, &socket_data->pseudo_header, &socket_data->headerlen))){ 381 fibril_rwlock_write_unlock(socket_data->local_lock); 382 return tcp_release_and_return(packet, ERROR_CODE); 383 } 384 }else if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, total_length))){ 364 365 if (error) 366 goto has_error_service; 367 368 if (socket_data->state == TCP_SOCKET_LISTEN) { 369 if (socket_data->pseudo_header) { 370 free(socket_data->pseudo_header); 371 socket_data->pseudo_header = NULL; 372 socket_data->headerlen = 0; 373 } 374 375 rc = ip_client_get_pseudo_header(IPPROTO_TCP, src, addrlen, 376 dest, addrlen, total_length, &socket_data->pseudo_header, 377 &socket_data->headerlen); 378 if (rc != EOK) { 385 379 fibril_rwlock_write_unlock(socket_data->local_lock); 386 return tcp_release_and_return(packet, ERROR_CODE); 387 } 388 checksum = compute_checksum(checksum, socket_data->pseudo_header, socket_data->headerlen); 389 if(flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO){ 390 printf("checksum err %x -> %x\n", header->checksum, flip_checksum(compact_checksum(checksum))); 380 return tcp_release_and_return(packet, rc); 381 } 382 } else { 383 rc = ip_client_set_pseudo_header_data_length( 384 socket_data->pseudo_header, socket_data->headerlen, 385 total_length); 386 if (rc != EOK) { 391 387 fibril_rwlock_write_unlock(socket_data->local_lock); 392 if(! ERROR_OCCURRED(tl_prepare_icmp_packet(tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error))){ 393 // checksum error ICMP 394 icmp_parameter_problem_msg(tcp_globals.icmp_phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->checksum)) - ((size_t) ((void *) header)), packet); 395 } 396 return EINVAL; 397 } 398 } 399 400 fibril_rwlock_read_unlock(&tcp_globals.lock); 401 402 // TODO error reporting/handling 403 // printf("st %d\n", socket_data->state); 404 switch(socket_data->state){ 405 case TCP_SOCKET_LISTEN: 406 ERROR_CODE = tcp_process_listen(socket, socket_data, header, packet, src, dest, addrlen); 407 break; 408 case TCP_SOCKET_SYN_RECEIVED: 409 ERROR_CODE = tcp_process_syn_received(socket, socket_data, header, packet); 410 break; 411 case TCP_SOCKET_SYN_SENT: 412 ERROR_CODE = tcp_process_syn_sent(socket, socket_data, header, packet); 413 break; 414 case TCP_SOCKET_FIN_WAIT_1: 415 // ack changing the state to FIN_WAIT_2 gets processed later 416 case TCP_SOCKET_FIN_WAIT_2: 417 // fin changing state to LAST_ACK gets processed later 418 case TCP_SOCKET_LAST_ACK: 419 // ack releasing the socket get processed later 420 case TCP_SOCKET_CLOSING: 421 // ack releasing the socket gets processed later 422 case TCP_SOCKET_ESTABLISHED: 423 ERROR_CODE = tcp_process_established(socket, socket_data, header, packet, fragments, total_length); 424 break; 425 default: 426 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 427 } 428 429 if(ERROR_CODE != EOK){ 430 printf("process %d\n", ERROR_CODE); 388 return tcp_release_and_return(packet, rc); 389 } 390 } 391 392 checksum = compute_checksum(checksum, socket_data->pseudo_header, 393 socket_data->headerlen); 394 if (flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO) { 395 printf("checksum err %x -> %x\n", header->checksum, 396 flip_checksum(compact_checksum(checksum))); 431 397 fibril_rwlock_write_unlock(socket_data->local_lock); 432 } 398 399 rc = tl_prepare_icmp_packet(tcp_globals.net_phone, 400 tcp_globals.icmp_phone, packet, error); 401 if (rc == EOK) { 402 /* Checksum error ICMP */ 403 icmp_parameter_problem_msg(tcp_globals.icmp_phone, 404 ICMP_PARAM_POINTER, 405 ((size_t) ((void *) &header->checksum)) - 406 ((size_t) ((void *) header)), packet); 407 } 408 409 return EINVAL; 410 } 411 412 has_error_service: 413 fibril_rwlock_write_unlock(&tcp_globals.lock); 414 415 /* TODO error reporting/handling */ 416 switch (socket_data->state) { 417 case TCP_SOCKET_LISTEN: 418 rc = tcp_process_listen(socket, socket_data, header, packet, 419 src, dest, addrlen); 420 break; 421 case TCP_SOCKET_SYN_RECEIVED: 422 rc = tcp_process_syn_received(socket, socket_data, header, 423 packet); 424 break; 425 case TCP_SOCKET_SYN_SENT: 426 rc = tcp_process_syn_sent(socket, socket_data, header, packet); 427 break; 428 case TCP_SOCKET_FIN_WAIT_1: 429 /* ack changing the state to FIN_WAIT_2 gets processed later */ 430 case TCP_SOCKET_FIN_WAIT_2: 431 /* fin changing state to LAST_ACK gets processed later */ 432 case TCP_SOCKET_LAST_ACK: 433 /* ack releasing the socket get processed later */ 434 case TCP_SOCKET_CLOSING: 435 /* ack releasing the socket gets processed later */ 436 case TCP_SOCKET_ESTABLISHED: 437 rc = tcp_process_established(socket, socket_data, header, 438 packet, fragments, total_length); 439 break; 440 default: 441 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 442 } 443 444 if (rc != EOK) { 445 fibril_rwlock_write_unlock(socket_data->local_lock); 446 printf("process %d\n", rc); 447 } 448 433 449 return EOK; 434 450 } 435 451 436 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){ 437 ERROR_DECLARE; 438 439 packet_t next_packet; 440 packet_t tmp_packet; 452 int tcp_process_established(socket_core_t *socket, tcp_socket_data_t * 453 socket_data, tcp_header_t *header, packet_t *packet, int fragments, 454 size_t total_length) 455 { 456 packet_t *next_packet; 457 packet_t *tmp_packet; 441 458 uint32_t old_incoming; 442 459 size_t order; … … 445 462 size_t offset; 446 463 uint32_t new_sequence_number; 464 bool forced_ack; 465 int rc; 447 466 448 467 assert(socket); … … 452 471 assert(packet); 453 472 473 forced_ack = false; 474 454 475 new_sequence_number = ntohl(header->sequence_number); 455 476 old_incoming = socket_data->next_incoming; 456 477 457 if(header->finalize){ 458 socket_data->fin_incoming = new_sequence_number; 459 } 460 461 // printf("pe %d < %d <= %d\n", new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length); 462 // trim begining if containing expected data 463 if(IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length)){ 464 // get the acknowledged offset 465 if(socket_data->next_incoming < new_sequence_number){ 466 offset = new_sequence_number - socket_data->next_incoming; 467 }else{ 468 offset = socket_data->next_incoming - new_sequence_number; 469 } 470 // printf("offset %d\n", offset); 478 if (header->finalize) { 479 socket_data->fin_incoming = new_sequence_number + 480 total_length - TCP_HEADER_LENGTH(header); 481 } 482 483 /* Trim begining if containing expected data */ 484 if (IS_IN_INTERVAL_OVERFLOW(new_sequence_number, 485 socket_data->next_incoming, new_sequence_number + total_length)) { 486 487 /* Get the acknowledged offset */ 488 if (socket_data->next_incoming < new_sequence_number) { 489 offset = new_sequence_number - 490 socket_data->next_incoming; 491 } else { 492 offset = socket_data->next_incoming - 493 new_sequence_number; 494 } 495 471 496 new_sequence_number += offset; 472 497 total_length -= offset; 473 498 length = packet_get_data_length(packet); 474 // trim the acknowledged data 475 while(length <= offset){ 476 // release the acknowledged packets 499 500 /* Trim the acknowledged data */ 501 while (length <= offset) { 502 /* Release the acknowledged packets */ 477 503 next_packet = pq_next(packet); 478 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 504 pq_release_remote(tcp_globals.net_phone, 505 packet_get_id(packet)); 479 506 packet = next_packet; 480 507 offset -= length; 481 508 length = packet_get_data_length(packet); 482 509 } 483 if((offset > 0) 484 && (ERROR_OCCURRED(packet_trim(packet, offset, 0)))){ 485 return tcp_release_and_return(packet, ERROR_CODE); 486 } 510 511 if (offset > 0) { 512 rc = packet_trim(packet, offset, 0); 513 if (rc != EOK) 514 return tcp_release_and_return(packet, rc); 515 } 516 487 517 assert(new_sequence_number == socket_data->next_incoming); 488 518 } 489 519 490 // release if overflowing the window 491 // if(IS_IN_INTERVAL_OVERFLOW(socket_data->next_incoming + socket_data->window, new_sequence_number, new_sequence_number + total_length)){ 492 // return tcp_release_and_return(packet, EOVERFLOW); 493 // } 494 520 /* Release if overflowing the window */ 495 521 /* 522 if (IS_IN_INTERVAL_OVERFLOW(socket_data->next_incoming + 523 socket_data->window, new_sequence_number, new_sequence_number + 524 total_length)) { 525 return tcp_release_and_return(packet, EOVERFLOW); 526 } 527 496 528 // trim end if overflowing the window 497 if(IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming + socket_data->window, new_sequence_number + total_length)){ 529 if (IS_IN_INTERVAL_OVERFLOW(new_sequence_number, 530 socket_data->next_incoming + socket_data->window, 531 new_sequence_number + total_length)) { 498 532 // get the allowed data length 499 if(socket_data->next_incoming + socket_data->window < new_sequence_number){ 500 offset = new_sequence_number - socket_data->next_incoming + socket_data->window; 501 }else{ 502 offset = socket_data->next_incoming + socket_data->window - new_sequence_number; 533 if (socket_data->next_incoming + socket_data->window < 534 new_sequence_number) { 535 offset = new_sequence_number - 536 socket_data->next_incoming + socket_data->window; 537 } else { 538 offset = socket_data->next_incoming + 539 socket_data->window - new_sequence_number; 503 540 } 504 541 next_packet = packet; 505 542 // trim the overflowing data 506 while (next_packet && (offset > 0)){543 while (next_packet && (offset > 0)) { 507 544 length = packet_get_data_length(packet); 508 if (length <= offset){545 if (length <= offset) 509 546 next_packet = pq_next(next_packet); 510 }else if(ERROR_OCCURRED(packet_trim(next_packet, 0, length - offset))){ 511 return tcp_release_and_return(packet, ERROR_CODE); 547 else { 548 rc = packet_trim(next_packet, 0, 549 length - offset)); 550 if (rc != EOK) 551 return tcp_release_and_return(packet, 552 rc); 512 553 } 513 554 offset -= length; … … 516 557 // release the overflowing packets 517 558 next_packet = pq_next(next_packet); 518 if (next_packet){559 if (next_packet) { 519 560 tmp_packet = next_packet; 520 561 next_packet = pq_next(next_packet); 521 562 pq_insert_after(tmp_packet, next_packet); 522 pq_release_remote(tcp_globals.net_phone, packet_get_id(tmp_packet)); 523 } 524 assert(new_sequence_number + total_length == socket_data->next_incoming + socket_data->window); 563 pq_release_remote(tcp_globals.net_phone, 564 packet_get_id(tmp_packet)); 565 } 566 assert(new_sequence_number + total_length == 567 socket_data->next_incoming + socket_data->window); 525 568 } 526 569 */ 527 / / the expected one arrived?528 if (new_sequence_number == socket_data->next_incoming){570 /* The expected one arrived? */ 571 if (new_sequence_number == socket_data->next_incoming) { 529 572 printf("expected\n"); 530 / / process acknowledgement573 /* Process acknowledgement */ 531 574 tcp_process_acknowledgement(socket, socket_data, header); 532 575 533 / / remove the header576 /* Remove the header */ 534 577 total_length -= TCP_HEADER_LENGTH(header); 535 if(ERROR_OCCURRED(packet_trim(packet, TCP_HEADER_LENGTH(header), 0))){ 536 return tcp_release_and_return(packet, ERROR_CODE); 537 } 538 539 if(total_length){ 540 ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, fragments, total_length)); 541 }else{ 578 rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0); 579 if (rc != EOK) 580 return tcp_release_and_return(packet, rc); 581 582 if (total_length) { 583 rc = tcp_queue_received_packet(socket, socket_data, 584 packet, fragments, total_length); 585 if (rc != EOK) 586 return rc; 587 } else { 542 588 total_length = 1; 543 589 } 590 544 591 socket_data->next_incoming = old_incoming + total_length; 545 592 packet = socket_data->incoming; 546 while(packet){ 547 if(ERROR_OCCURRED(pq_get_order(socket_data->incoming, &order, NULL))){ 548 // remove the corrupted packet 593 while (packet) { 594 rc = pq_get_order(socket_data->incoming, &order, NULL); 595 if (rc != EOK) { 596 /* Remove the corrupted packet */ 549 597 next_packet = pq_detach(packet); 550 if (packet == socket_data->incoming){598 if (packet == socket_data->incoming) 551 599 socket_data->incoming = next_packet; 552 }553 pq_release_remote(tcp_globals.net_phone,packet_get_id(packet));600 pq_release_remote(tcp_globals.net_phone, 601 packet_get_id(packet)); 554 602 packet = next_packet; 555 603 continue; 556 604 } 605 557 606 sequence_number = (uint32_t) order; 558 if(IS_IN_INTERVAL_OVERFLOW(sequence_number, old_incoming, socket_data->next_incoming)){ 559 // move to the next 607 if (IS_IN_INTERVAL_OVERFLOW(sequence_number, 608 old_incoming, socket_data->next_incoming)) { 609 /* Move to the next */ 560 610 packet = pq_next(packet); 561 // coninual data? 562 }else if(IS_IN_INTERVAL_OVERFLOW(old_incoming, sequence_number, socket_data->next_incoming)){ 563 // detach the packet 611 /* Coninual data? */ 612 } else if (IS_IN_INTERVAL_OVERFLOW(old_incoming, 613 sequence_number, socket_data->next_incoming)) { 614 /* Detach the packet */ 564 615 next_packet = pq_detach(packet); 565 if (packet == socket_data->incoming){616 if (packet == socket_data->incoming) 566 617 socket_data->incoming = next_packet; 567 } 568 // get data length 618 /* Get data length */ 569 619 length = packet_get_data_length(packet); 570 620 new_sequence_number = sequence_number + length; 571 if(length <= 0){ 572 // remove the empty packet 573 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 621 if (length <= 0) { 622 /* Remove the empty packet */ 623 pq_release_remote(tcp_globals.net_phone, 624 packet_get_id(packet)); 574 625 packet = next_packet; 575 626 continue; 576 627 } 577 // exactly following 578 if(sequence_number == socket_data->next_incoming){ 579 // queue received data 580 ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet))); 581 socket_data->next_incoming = new_sequence_number; 628 /* Exactly following */ 629 if (sequence_number == 630 socket_data->next_incoming) { 631 /* Queue received data */ 632 rc = tcp_queue_received_packet(socket, 633 socket_data, packet, 1, 634 packet_get_data_length(packet)); 635 if (rc != EOK) 636 return rc; 637 socket_data->next_incoming = 638 new_sequence_number; 582 639 packet = next_packet; 583 640 continue; 584 // at least partly following data? 585 }else if(IS_IN_INTERVAL_OVERFLOW(sequence_number, socket_data->next_incoming, new_sequence_number)){ 586 if(socket_data->next_incoming < new_sequence_number){ 587 length = new_sequence_number - socket_data->next_incoming; 588 }else{ 589 length = socket_data->next_incoming - new_sequence_number; 641 /* At least partly following data? */ 642 } 643 if (IS_IN_INTERVAL_OVERFLOW(sequence_number, 644 socket_data->next_incoming, new_sequence_number)) { 645 if (socket_data->next_incoming < 646 new_sequence_number) { 647 length = new_sequence_number - 648 socket_data->next_incoming; 649 } else { 650 length = 651 socket_data->next_incoming - 652 new_sequence_number; 590 653 } 591 if(! ERROR_OCCURRED(packet_trim(packet, length, 0))){ 592 // queue received data 593 ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet))); 594 socket_data->next_incoming = new_sequence_number; 654 rc = packet_trim(packet,length, 0); 655 if (rc == EOK) { 656 /* Queue received data */ 657 rc = tcp_queue_received_packet( 658 socket, socket_data, packet, 659 1, packet_get_data_length( 660 packet)); 661 if (rc != EOK) 662 return rc; 663 socket_data->next_incoming = 664 new_sequence_number; 595 665 packet = next_packet; 596 666 continue; 597 667 } 598 668 } 599 // remove the duplicit or corrupted packet 600 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 669 /* Remove the duplicit or corrupted packet */ 670 pq_release_remote(tcp_globals.net_phone, 671 packet_get_id(packet)); 601 672 packet = next_packet; 602 673 continue; 603 } else{674 } else { 604 675 break; 605 676 } 606 677 } 607 }else if(IS_IN_INTERVAL(socket_data->next_incoming, new_sequence_number, socket_data->next_incoming + socket_data->window)){ 678 } else if (IS_IN_INTERVAL(socket_data->next_incoming, 679 new_sequence_number, 680 socket_data->next_incoming + socket_data->window)) { 608 681 printf("in window\n"); 609 / / process acknowledgement682 /* Process acknowledgement */ 610 683 tcp_process_acknowledgement(socket, socket_data, header); 611 684 612 / / remove the header685 /* Remove the header */ 613 686 total_length -= TCP_HEADER_LENGTH(header); 614 if(ERROR_OCCURRED(packet_trim(packet, TCP_HEADER_LENGTH(header), 0))){615 return tcp_release_and_return(packet, ERROR_CODE);616 }687 rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0); 688 if (rc != EOK) 689 return tcp_release_and_return(packet, rc); 617 690 618 691 next_packet = pq_detach(packet); 619 692 length = packet_get_data_length(packet); 620 if(ERROR_OCCURRED(pq_add(&socket_data->incoming, packet, new_sequence_number, length))){ 621 // remove the corrupted packets 622 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 623 pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet)); 624 }else{ 625 while(next_packet){ 693 rc = pq_add(&socket_data->incoming, packet, new_sequence_number, 694 length); 695 if (rc != EOK) { 696 /* Remove the corrupted packets */ 697 pq_release_remote(tcp_globals.net_phone, 698 packet_get_id(packet)); 699 pq_release_remote(tcp_globals.net_phone, 700 packet_get_id(next_packet)); 701 } else { 702 while (next_packet) { 626 703 new_sequence_number += length; 627 704 tmp_packet = pq_detach(next_packet); 628 705 length = packet_get_data_length(next_packet); 629 if(ERROR_OCCURRED(pq_set_order(next_packet, new_sequence_number, length)) 630 || ERROR_OCCURRED(pq_insert_after(packet, next_packet))){ 631 pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet)); 706 707 rc = pq_set_order(next_packet, 708 new_sequence_number, length); 709 if (rc != EOK) { 710 pq_release_remote(tcp_globals.net_phone, 711 packet_get_id(next_packet)); 712 } 713 rc = pq_insert_after(packet, next_packet); 714 if (rc != EOK) { 715 pq_release_remote(tcp_globals.net_phone, 716 packet_get_id(next_packet)); 632 717 } 633 718 next_packet = tmp_packet; 634 719 } 635 720 } 636 } else{721 } else { 637 722 printf("unexpected\n"); 638 / / release duplicite or restricted723 /* Release duplicite or restricted */ 639 724 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 640 } 641 642 // change state according to the acknowledging incoming fin 643 if(IS_IN_INTERVAL_OVERFLOW(old_incoming, socket_data->fin_incoming, socket_data->next_incoming)){ 644 switch(socket_data->state){ 645 case TCP_SOCKET_FIN_WAIT_1: 646 case TCP_SOCKET_FIN_WAIT_2: 647 case TCP_SOCKET_CLOSING: 648 socket_data->state = TCP_SOCKET_CLOSING; 649 break; 650 //case TCP_ESTABLISHED: 651 default: 652 socket_data->state = TCP_SOCKET_CLOSE_WAIT; 653 break; 725 forced_ack = true; 726 } 727 728 /* If next in sequence is an incoming FIN */ 729 if (socket_data->next_incoming == socket_data->fin_incoming) { 730 /* Advance sequence number */ 731 socket_data->next_incoming += 1; 732 733 /* Handle FIN */ 734 switch (socket_data->state) { 735 case TCP_SOCKET_FIN_WAIT_1: 736 case TCP_SOCKET_FIN_WAIT_2: 737 case TCP_SOCKET_CLOSING: 738 socket_data->state = TCP_SOCKET_CLOSING; 739 break; 740 case TCP_SOCKET_ESTABLISHED: 741 /* Queue end-of-data marker on the socket. */ 742 tcp_queue_received_end_of_data(socket); 743 socket_data->state = TCP_SOCKET_CLOSE_WAIT; 744 break; 745 default: 746 socket_data->state = TCP_SOCKET_CLOSE_WAIT; 747 break; 654 748 } 655 749 } 656 750 657 751 packet = tcp_get_packets_to_send(socket, socket_data); 658 if(! packet){ 659 // create the notification packet 660 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 0)); 661 ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, 1)); 662 packet = tcp_send_prepare_packet(socket, socket_data, packet, 1, socket_data->last_outgoing + 1); 663 } 752 if (!packet && (socket_data->next_incoming != old_incoming || forced_ack)) { 753 /* Create the notification packet */ 754 rc = tcp_create_notification_packet(&packet, socket, 755 socket_data, 0, 0); 756 if (rc != EOK) 757 return rc; 758 rc = tcp_queue_prepare_packet(socket, socket_data, packet, 1); 759 if (rc != EOK) 760 return rc; 761 packet = tcp_send_prepare_packet(socket, socket_data, packet, 1, 762 socket_data->last_outgoing + 1); 763 } 764 664 765 fibril_rwlock_write_unlock(socket_data->local_lock); 665 // send the packet 766 767 /* Send the packet */ 666 768 tcp_send_packets(socket_data->device_id, packet); 769 667 770 return EOK; 668 771 } 669 772 670 int tcp_queue_received_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length){ 671 ERROR_DECLARE; 672 673 packet_dimension_ref packet_dimension; 773 int tcp_queue_received_packet(socket_core_t *socket, 774 tcp_socket_data_t *socket_data, packet_t *packet, int fragments, 775 size_t total_length) 776 { 777 packet_dimension_t *packet_dimension; 778 int rc; 674 779 675 780 assert(socket); … … 680 785 assert(socket_data->window > total_length); 681 786 682 // queue the received packet 683 if(ERROR_OCCURRED(dyn_fifo_push(&socket->received, packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE)) 684 || ERROR_OCCURRED(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension))){ 685 return tcp_release_and_return(packet, ERROR_CODE); 686 } 687 688 // decrease the window size 787 /* Queue the received packet */ 788 rc = dyn_fifo_push(&socket->received, packet_get_id(packet), 789 SOCKET_MAX_RECEIVED_SIZE); 790 if (rc != EOK) 791 return tcp_release_and_return(packet, rc); 792 rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone, 793 &tcp_globals.dimensions, socket_data->device_id, &packet_dimension); 794 if (rc != EOK) 795 return tcp_release_and_return(packet, rc); 796 797 /* Decrease the window size */ 689 798 socket_data->window -= total_length; 690 799 691 // notify the destination socket 692 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); 800 /* Notify the destination socket */ 801 async_msg_5(socket->phone, NET_SOCKET_RECEIVED, 802 (sysarg_t) socket->socket_id, 803 ((packet_dimension->content < socket_data->data_fragment_size) ? 804 packet_dimension->content : socket_data->data_fragment_size), 0, 0, 805 (sysarg_t) fragments); 806 693 807 return EOK; 694 808 } 695 809 696 int tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){ 697 ERROR_DECLARE; 698 699 packet_t next_packet; 810 /** Queue end-of-data marker on the socket. 811 * 812 * Next element in the sequence space is FIN. Queue end-of-data marker 813 * on the socket. 814 * 815 * @param socket Socket 816 */ 817 static void tcp_queue_received_end_of_data(socket_core_t *socket) 818 { 819 assert(socket != NULL); 820 821 /* Notify the destination socket */ 822 async_msg_5(socket->phone, NET_SOCKET_RECEIVED, 823 (sysarg_t) socket->socket_id, 824 0, 0, 0, 825 (sysarg_t) 0 /* 0 fragments == no more data */); 826 } 827 828 int tcp_process_syn_sent(socket_core_t *socket, tcp_socket_data_t * 829 socket_data, tcp_header_t *header, packet_t *packet) 830 { 831 packet_t *next_packet; 832 int rc; 700 833 701 834 assert(socket); … … 705 838 assert(packet); 706 839 707 if(header->synchronize){ 708 // process acknowledgement 709 tcp_process_acknowledgement(socket, socket_data, header); 710 711 socket_data->next_incoming = ntohl(header->sequence_number) + 1; 712 // release additional packets 713 next_packet = pq_detach(packet); 714 if(next_packet){ 715 pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet)); 716 } 717 // trim if longer than the header 718 if((packet_get_data_length(packet) > sizeof(*header)) 719 && ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - sizeof(*header)))){ 720 return tcp_release_and_return(packet, ERROR_CODE); 721 } 722 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); 723 fibril_mutex_lock(&socket_data->operation.mutex); 724 socket_data->operation.result = tcp_queue_packet(socket, socket_data, packet, 1); 725 if(socket_data->operation.result == EOK){ 726 socket_data->state = TCP_SOCKET_ESTABLISHED; 727 packet = tcp_get_packets_to_send(socket, socket_data); 728 if(packet){ 729 fibril_rwlock_write_unlock(socket_data->local_lock); 730 // send the packet 731 tcp_send_packets(socket_data->device_id, packet); 732 // signal the result 733 fibril_condvar_signal(&socket_data->operation.condvar); 734 fibril_mutex_unlock(&socket_data->operation.mutex); 735 return EOK; 736 } 737 } 738 fibril_mutex_unlock(&socket_data->operation.mutex); 739 } 840 if (!header->synchronize) 841 return tcp_release_and_return(packet, EINVAL); 842 843 /* Process acknowledgement */ 844 tcp_process_acknowledgement(socket, socket_data, header); 845 846 socket_data->next_incoming = ntohl(header->sequence_number) + 1; 847 848 /* Release additional packets */ 849 next_packet = pq_detach(packet); 850 if (next_packet) { 851 pq_release_remote(tcp_globals.net_phone, 852 packet_get_id(next_packet)); 853 } 854 855 /* Trim if longer than the header */ 856 if (packet_get_data_length(packet) > sizeof(*header)) { 857 rc = packet_trim(packet, 0, 858 packet_get_data_length(packet) - sizeof(*header)); 859 if (rc != EOK) 860 return tcp_release_and_return(packet, rc); 861 } 862 863 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); 864 fibril_mutex_lock(&socket_data->operation.mutex); 865 socket_data->operation.result = tcp_queue_packet(socket, socket_data, 866 packet, 1); 867 868 if (socket_data->operation.result == EOK) { 869 socket_data->state = TCP_SOCKET_ESTABLISHED; 870 packet = tcp_get_packets_to_send(socket, socket_data); 871 if (packet) { 872 fibril_rwlock_write_unlock( socket_data->local_lock); 873 /* Send the packet */ 874 tcp_send_packets(socket_data->device_id, packet); 875 /* Signal the result */ 876 fibril_condvar_signal( &socket_data->operation.condvar); 877 fibril_mutex_unlock( &socket_data->operation.mutex); 878 return EOK; 879 } 880 } 881 882 fibril_mutex_unlock(&socket_data->operation.mutex); 740 883 return tcp_release_and_return(packet, EINVAL); 741 884 } 742 885 743 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){ 744 ERROR_DECLARE; 745 746 packet_t next_packet; 747 socket_core_ref socket; 748 tcp_socket_data_ref socket_data; 886 int tcp_process_listen(socket_core_t *listening_socket, 887 tcp_socket_data_t *listening_socket_data, tcp_header_t *header, 888 packet_t *packet, struct sockaddr *src, struct sockaddr *dest, 889 size_t addrlen) 890 { 891 packet_t *next_packet; 892 socket_core_t *socket; 893 tcp_socket_data_t *socket_data; 749 894 int socket_id; 750 895 int listening_socket_id = listening_socket->socket_id; 751 896 int listening_port = listening_socket->port; 897 int rc; 752 898 753 899 assert(listening_socket); … … 757 903 assert(packet); 758 904 759 // printf("syn %d\n", header->synchronize); 760 if(header->synchronize){ 761 socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data)); 762 if(! socket_data){ 763 return tcp_release_and_return(packet, ENOMEM); 764 }else{ 765 tcp_initialize_socket_data(socket_data); 766 socket_data->local_lock = listening_socket_data->local_lock; 767 socket_data->local_sockets = listening_socket_data->local_sockets; 768 socket_data->listening_socket_id = listening_socket->socket_id; 769 770 socket_data->next_incoming = ntohl(header->sequence_number); 771 socket_data->treshold = socket_data->next_incoming + ntohs(header->window); 772 773 socket_data->addrlen = addrlen; 774 socket_data->addr = malloc(socket_data->addrlen); 775 if(! socket_data->addr){ 776 free(socket_data); 777 return tcp_release_and_return(packet, ENOMEM); 778 } 779 memcpy(socket_data->addr, src, socket_data->addrlen); 780 781 socket_data->dest_port = ntohs(header->source_port); 782 if(ERROR_OCCURRED(tl_set_address_port(socket_data->addr, socket_data->addrlen, socket_data->dest_port))){ 783 free(socket_data->addr); 784 free(socket_data); 785 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 786 return ERROR_CODE; 787 } 788 789 // printf("addr %p\n", socket_data->addr, socket_data->addrlen); 790 // create a socket 791 socket_id = -1; 792 if(ERROR_OCCURRED(socket_create(socket_data->local_sockets, listening_socket->phone, socket_data, &socket_id))){ 793 free(socket_data->addr); 794 free(socket_data); 795 return tcp_release_and_return(packet, ERROR_CODE); 796 } 797 798 printf("new_sock %d\n", socket_id); 799 socket_data->pseudo_header = listening_socket_data->pseudo_header; 800 socket_data->headerlen = listening_socket_data->headerlen; 801 listening_socket_data->pseudo_header = NULL; 802 listening_socket_data->headerlen = 0; 803 804 fibril_rwlock_write_unlock(socket_data->local_lock); 805 // printf("list lg\n"); 806 fibril_rwlock_write_lock(&tcp_globals.lock); 807 // printf("list locked\n"); 808 // find the destination socket 809 listening_socket = socket_port_find(&tcp_globals.sockets, listening_port, SOCKET_MAP_KEY_LISTENING, 0); 810 if((! listening_socket) || (listening_socket->socket_id != listening_socket_id)){ 811 fibril_rwlock_write_unlock(&tcp_globals.lock); 812 // a shadow may remain until app hangs up 813 return tcp_release_and_return(packet, EOK/*ENOTSOCK*/); 814 } 815 // printf("port %d\n", listening_socket->port); 816 listening_socket_data = (tcp_socket_data_ref) listening_socket->specific_data; 817 assert(listening_socket_data); 818 819 // printf("list ll\n"); 820 fibril_rwlock_write_lock(listening_socket_data->local_lock); 821 // printf("list locked\n"); 822 823 socket = socket_cores_find(listening_socket_data->local_sockets, socket_id); 824 if(! socket){ 825 // where is the socket?!? 826 fibril_rwlock_write_unlock(&tcp_globals.lock); 827 return ENOTSOCK; 828 } 829 socket_data = (tcp_socket_data_ref) socket->specific_data; 830 assert(socket_data); 831 832 // uint8_t * data = socket_data->addr; 833 // 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]); 834 835 ERROR_CODE = socket_port_add(&tcp_globals.sockets, listening_port, socket, (const char *) socket_data->addr, socket_data->addrlen); 836 assert(socket == socket_port_find(&tcp_globals.sockets, listening_port, (const char *) socket_data->addr, socket_data->addrlen)); 837 //ERROR_CODE = socket_bind_free_port(&tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port); 838 //tcp_globals.last_used_port = socket->port; 839 // printf("bound %d\n", socket->port); 840 fibril_rwlock_write_unlock(&tcp_globals.lock); 841 if(ERROR_CODE != EOK){ 842 socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 843 return tcp_release_and_return(packet, ERROR_CODE); 844 } 845 846 socket_data->state = TCP_SOCKET_LISTEN; 847 socket_data->next_incoming = ntohl(header->sequence_number) + 1; 848 // release additional packets 849 next_packet = pq_detach(packet); 850 if(next_packet){ 851 pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet)); 852 } 853 // trim if longer than the header 854 if((packet_get_data_length(packet) > sizeof(*header)) 855 && ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - sizeof(*header)))){ 856 socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 857 return tcp_release_and_return(packet, ERROR_CODE); 858 } 859 tcp_prepare_operation_header(socket, socket_data, header, 1, 0); 860 if(ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1))){ 861 socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 862 return ERROR_CODE; 863 } 864 packet = tcp_get_packets_to_send(socket, socket_data); 865 // printf("send %d\n", packet_get_id(packet)); 866 if(! packet){ 867 socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 868 return EINVAL; 869 }else{ 870 socket_data->state = TCP_SOCKET_SYN_RECEIVED; 871 // printf("unlock\n"); 872 fibril_rwlock_write_unlock(socket_data->local_lock); 873 // send the packet 874 tcp_send_packets(socket_data->device_id, packet); 875 return EOK; 876 } 877 } 878 } 879 return tcp_release_and_return(packet, EINVAL); 880 } 881 882 int tcp_process_syn_received(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){ 883 ERROR_DECLARE; 884 885 socket_core_ref listening_socket; 886 tcp_socket_data_ref listening_socket_data; 905 if (!header->synchronize) 906 return tcp_release_and_return(packet, EINVAL); 907 908 socket_data = (tcp_socket_data_t *) malloc(sizeof(*socket_data)); 909 if (!socket_data) 910 return tcp_release_and_return(packet, ENOMEM); 911 912 tcp_initialize_socket_data(socket_data); 913 socket_data->local_lock = listening_socket_data->local_lock; 914 socket_data->local_sockets = listening_socket_data->local_sockets; 915 socket_data->listening_socket_id = listening_socket->socket_id; 916 socket_data->next_incoming = ntohl(header->sequence_number); 917 socket_data->treshold = socket_data->next_incoming + 918 ntohs(header->window); 919 socket_data->addrlen = addrlen; 920 socket_data->addr = malloc(socket_data->addrlen); 921 if (!socket_data->addr) { 922 free(socket_data); 923 return tcp_release_and_return(packet, ENOMEM); 924 } 925 926 memcpy(socket_data->addr, src, socket_data->addrlen); 927 socket_data->dest_port = ntohs(header->source_port); 928 rc = tl_set_address_port(socket_data->addr, socket_data->addrlen, 929 socket_data->dest_port); 930 if (rc != EOK) { 931 free(socket_data->addr); 932 free(socket_data); 933 return tcp_release_and_return(packet, rc); 934 } 935 936 /* Create a socket */ 937 socket_id = -1; 938 rc = socket_create(socket_data->local_sockets, listening_socket->phone, 939 socket_data, &socket_id); 940 if (rc != EOK) { 941 free(socket_data->addr); 942 free(socket_data); 943 return tcp_release_and_return(packet, rc); 944 } 945 946 printf("new_sock %d\n", socket_id); 947 socket_data->pseudo_header = listening_socket_data->pseudo_header; 948 socket_data->headerlen = listening_socket_data->headerlen; 949 listening_socket_data->pseudo_header = NULL; 950 listening_socket_data->headerlen = 0; 951 952 fibril_rwlock_write_unlock(socket_data->local_lock); 953 fibril_rwlock_write_lock(&tcp_globals.lock); 954 955 /* Find the destination socket */ 956 listening_socket = socket_port_find(&tcp_globals.sockets, 957 listening_port, (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0); 958 if (!listening_socket || 959 (listening_socket->socket_id != listening_socket_id)) { 960 fibril_rwlock_write_unlock(&tcp_globals.lock); 961 /* A shadow may remain until app hangs up */ 962 return tcp_release_and_return(packet, EOK /*ENOTSOCK*/); 963 } 964 listening_socket_data = 965 (tcp_socket_data_t *) listening_socket->specific_data; 966 assert(listening_socket_data); 967 968 fibril_rwlock_write_lock(listening_socket_data->local_lock); 969 970 socket = socket_cores_find(listening_socket_data->local_sockets, 971 socket_id); 972 if (!socket) { 973 /* Where is the socket?!? */ 974 fibril_rwlock_write_unlock(&tcp_globals.lock); 975 return ENOTSOCK; 976 } 977 socket_data = (tcp_socket_data_t *) socket->specific_data; 978 assert(socket_data); 979 980 rc = socket_port_add(&tcp_globals.sockets, listening_port, socket, 981 (uint8_t *) socket_data->addr, socket_data->addrlen); 982 assert(socket == socket_port_find(&tcp_globals.sockets, listening_port, 983 (uint8_t *) socket_data->addr, socket_data->addrlen)); 984 985 // rc = socket_bind_free_port(&tcp_globals.sockets, socket, 986 // TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, 987 // tcp_globals.last_used_port); 988 // tcp_globals.last_used_port = socket->port; 989 fibril_rwlock_write_unlock(&tcp_globals.lock); 990 if (rc != EOK) { 991 socket_destroy(tcp_globals.net_phone, socket->socket_id, 992 socket_data->local_sockets, &tcp_globals.sockets, 993 tcp_free_socket_data); 994 return tcp_release_and_return(packet, rc); 995 } 996 997 socket_data->state = TCP_SOCKET_LISTEN; 998 socket_data->next_incoming = ntohl(header->sequence_number) + 1; 999 1000 /* Release additional packets */ 1001 next_packet = pq_detach(packet); 1002 if (next_packet) { 1003 pq_release_remote(tcp_globals.net_phone, 1004 packet_get_id(next_packet)); 1005 } 1006 1007 /* Trim if longer than the header */ 1008 if (packet_get_data_length(packet) > sizeof(*header)) { 1009 rc = packet_trim(packet, 0, 1010 packet_get_data_length(packet) - sizeof(*header)); 1011 if (rc != EOK) { 1012 socket_destroy(tcp_globals.net_phone, socket->socket_id, 1013 socket_data->local_sockets, &tcp_globals.sockets, 1014 tcp_free_socket_data); 1015 return tcp_release_and_return(packet, rc); 1016 } 1017 } 1018 1019 tcp_prepare_operation_header(socket, socket_data, header, 1, 0); 1020 1021 rc = tcp_queue_packet(socket, socket_data, packet, 1); 1022 if (rc != EOK) { 1023 socket_destroy(tcp_globals.net_phone, socket->socket_id, 1024 socket_data->local_sockets, &tcp_globals.sockets, 1025 tcp_free_socket_data); 1026 return rc; 1027 } 1028 1029 packet = tcp_get_packets_to_send(socket, socket_data); 1030 if (!packet) { 1031 socket_destroy(tcp_globals.net_phone, socket->socket_id, 1032 socket_data->local_sockets, &tcp_globals.sockets, 1033 tcp_free_socket_data); 1034 return EINVAL; 1035 } 1036 1037 socket_data->state = TCP_SOCKET_SYN_RECEIVED; 1038 fibril_rwlock_write_unlock(socket_data->local_lock); 1039 1040 /* Send the packet */ 1041 tcp_send_packets(socket_data->device_id, packet); 1042 1043 return EOK; 1044 } 1045 1046 int tcp_process_syn_received(socket_core_t *socket, 1047 tcp_socket_data_t *socket_data, tcp_header_t *header, packet_t *packet) 1048 { 1049 socket_core_t *listening_socket; 1050 tcp_socket_data_t *listening_socket_data; 1051 int rc; 887 1052 888 1053 assert(socket); … … 892 1057 assert(packet); 893 1058 894 printf("syn_rec\n"); 895 if(header->acknowledge){ 896 // process acknowledgement 897 tcp_process_acknowledgement(socket, socket_data, header); 898 899 socket_data->next_incoming = ntohl(header->sequence_number);// + 1; 900 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 901 socket_data->state = TCP_SOCKET_ESTABLISHED; 902 listening_socket = socket_cores_find(socket_data->local_sockets, socket_data->listening_socket_id); 903 if(listening_socket){ 904 listening_socket_data = (tcp_socket_data_ref) listening_socket->specific_data; 905 assert(listening_socket_data); 906 907 // queue the received packet 908 if(! ERROR_OCCURRED(dyn_fifo_push(&listening_socket->accepted, (-1 * socket->socket_id), listening_socket_data->backlog))){ 909 // notify the destination socket 910 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); 911 fibril_rwlock_write_unlock(socket_data->local_lock); 912 return EOK; 913 } 914 } 915 // send FIN 916 socket_data->state = TCP_SOCKET_FIN_WAIT_1; 917 918 // create the notification packet 919 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1)); 920 921 // send the packet 922 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1)); 923 924 // flush packets 925 packet = tcp_get_packets_to_send(socket, socket_data); 926 fibril_rwlock_write_unlock(socket_data->local_lock); 927 if(packet){ 928 // send the packet 929 tcp_send_packets(socket_data->device_id, packet); 930 } 931 return EOK; 932 }else{ 1059 if (!header->acknowledge) 933 1060 return tcp_release_and_return(packet, EINVAL); 934 } 935 return EINVAL; 936 } 937 938 void tcp_process_acknowledgement(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header){ 1061 1062 /* Process acknowledgement */ 1063 tcp_process_acknowledgement(socket, socket_data, header); 1064 1065 socket_data->next_incoming = ntohl(header->sequence_number); /* + 1; */ 1066 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1067 socket_data->state = TCP_SOCKET_ESTABLISHED; 1068 listening_socket = socket_cores_find(socket_data->local_sockets, 1069 socket_data->listening_socket_id); 1070 if (listening_socket) { 1071 listening_socket_data = 1072 (tcp_socket_data_t *) listening_socket->specific_data; 1073 assert(listening_socket_data); 1074 1075 /* Queue the received packet */ 1076 rc = dyn_fifo_push(&listening_socket->accepted, 1077 (-1 * socket->socket_id), listening_socket_data->backlog); 1078 if (rc == EOK) { 1079 /* Notify the destination socket */ 1080 async_msg_5(socket->phone, NET_SOCKET_ACCEPTED, 1081 (sysarg_t) listening_socket->socket_id, 1082 socket_data->data_fragment_size, TCP_HEADER_SIZE, 1083 0, (sysarg_t) socket->socket_id); 1084 1085 fibril_rwlock_write_unlock(socket_data->local_lock); 1086 return EOK; 1087 } 1088 } 1089 /* Send FIN */ 1090 socket_data->state = TCP_SOCKET_FIN_WAIT_1; 1091 1092 /* Create the notification packet */ 1093 rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1); 1094 if (rc != EOK) 1095 return rc; 1096 1097 /* Send the packet */ 1098 rc = tcp_queue_packet(socket, socket_data, packet, 1); 1099 if (rc != EOK) 1100 return rc; 1101 1102 /* Flush packets */ 1103 packet = tcp_get_packets_to_send(socket, socket_data); 1104 fibril_rwlock_write_unlock(socket_data->local_lock); 1105 if (packet) { 1106 /* Send the packet */ 1107 tcp_send_packets(socket_data->device_id, packet); 1108 } 1109 1110 return EOK; 1111 } 1112 1113 void tcp_process_acknowledgement(socket_core_t *socket, 1114 tcp_socket_data_t *socket_data, tcp_header_t *header) 1115 { 939 1116 size_t number; 940 1117 size_t length; 941 packet_t packet;942 packet_t next;943 packet_t acknowledged = NULL;1118 packet_t *packet; 1119 packet_t *next; 1120 packet_t *acknowledged = NULL; 944 1121 uint32_t old; 945 1122 … … 949 1126 assert(header); 950 1127 951 if(header->acknowledge){ 952 number = ntohl(header->acknowledgement_number); 953 // if more data acknowledged 954 if(number != socket_data->expected){ 955 old = socket_data->expected; 956 if(IS_IN_INTERVAL_OVERFLOW(old, socket_data->fin_outgoing, number)){ 957 switch(socket_data->state){ 958 case TCP_SOCKET_FIN_WAIT_1: 959 socket_data->state = TCP_SOCKET_FIN_WAIT_2; 960 break; 961 case TCP_SOCKET_LAST_ACK: 962 case TCP_SOCKET_CLOSING: 963 // fin acknowledged - release the socket in another fibril 964 tcp_prepare_timeout(tcp_release_after_timeout, socket, socket_data, 0, TCP_SOCKET_TIME_WAIT, NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true); 965 break; 966 default: 967 break; 968 } 1128 if (!header->acknowledge) 1129 return; 1130 1131 number = ntohl(header->acknowledgement_number); 1132 1133 /* If more data acknowledged */ 1134 if (number != socket_data->expected) { 1135 old = socket_data->expected; 1136 if (IS_IN_INTERVAL_OVERFLOW(old, socket_data->fin_outgoing, 1137 number)) { 1138 switch (socket_data->state) { 1139 case TCP_SOCKET_FIN_WAIT_1: 1140 socket_data->state = TCP_SOCKET_FIN_WAIT_2; 1141 break; 1142 case TCP_SOCKET_LAST_ACK: 1143 case TCP_SOCKET_CLOSING: 1144 /* 1145 * FIN acknowledged - release the socket in 1146 * another fibril. 1147 */ 1148 tcp_prepare_timeout(tcp_release_after_timeout, 1149 socket, socket_data, 0, 1150 TCP_SOCKET_TIME_WAIT, 1151 NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true); 1152 break; 1153 default: 1154 break; 969 1155 } 970 // update the treshold if higher than set 971 if(number + ntohs(header->window) > socket_data->expected + socket_data->treshold){ 972 socket_data->treshold = number + ntohs(header->window) - socket_data->expected; 973 } 974 // set new expected sequence number 975 socket_data->expected = number; 1156 } 1157 1158 /* Update the treshold if higher than set */ 1159 if (number + ntohs(header->window) > 1160 socket_data->expected + socket_data->treshold) { 1161 socket_data->treshold = number + ntohs(header->window) - 1162 socket_data->expected; 1163 } 1164 1165 /* Set new expected sequence number */ 1166 socket_data->expected = number; 1167 socket_data->expected_count = 1; 1168 packet = socket_data->outgoing; 1169 while (pq_get_order(packet, &number, &length) == EOK) { 1170 if (IS_IN_INTERVAL_OVERFLOW((uint32_t) old, 1171 (uint32_t) (number + length), 1172 (uint32_t) socket_data->expected)) { 1173 next = pq_detach(packet); 1174 if (packet == socket_data->outgoing) 1175 socket_data->outgoing = next; 1176 1177 /* Add to acknowledged or release */ 1178 if (pq_add(&acknowledged, packet, 0, 0) != EOK) 1179 pq_release_remote(tcp_globals.net_phone, 1180 packet_get_id(packet)); 1181 packet = next; 1182 } else if (old < socket_data->expected) 1183 break; 1184 } 1185 1186 /* Release acknowledged */ 1187 if (acknowledged) { 1188 pq_release_remote(tcp_globals.net_phone, 1189 packet_get_id(acknowledged)); 1190 } 1191 return; 1192 /* If the same as the previous time */ 1193 } 1194 1195 if (number == socket_data->expected) { 1196 /* Increase the counter */ 1197 socket_data->expected_count++; 1198 if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) { 976 1199 socket_data->expected_count = 1; 977 packet = socket_data->outgoing; 978 while(pq_get_order(packet, &number, &length) == EOK){ 979 if(IS_IN_INTERVAL_OVERFLOW((uint32_t) old, (uint32_t)(number + length), (uint32_t) socket_data->expected)){ 980 next = pq_detach(packet); 981 if(packet == socket_data->outgoing){ 982 socket_data->outgoing = next; 983 } 984 // add to acknowledged or release 985 if(pq_add(&acknowledged, packet, 0, 0) != EOK){ 986 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 987 } 988 packet = next; 989 }else if(old < socket_data->expected){ 990 break; 991 } 992 } 993 // release acknowledged 994 if(acknowledged){ 995 pq_release_remote(tcp_globals.net_phone, packet_get_id(acknowledged)); 996 } 997 return; 998 // if the same as the previous time 999 }else if(number == socket_data->expected){ 1000 // increase the counter 1001 ++ socket_data->expected_count; 1002 if(socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT){ 1003 socket_data->expected_count = 1; 1004 // TODO retransmit lock 1005 //tcp_retransmit_packet(socket, socket_data, number); 1006 } 1007 } 1008 } 1009 } 1010 1011 int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 1012 ERROR_DECLARE; 1013 1014 packet_t packet; 1015 1200 /* TODO retransmit lock */ 1201 //tcp_retransmit_packet(socket, socket_data, number); 1202 } 1203 } 1204 } 1205 1206 /** Per-connection initialization 1207 * 1208 */ 1209 void tl_connection(void) 1210 { 1211 } 1212 1213 /** Processes the TCP message. 1214 * 1215 * @param[in] callid The message identifier. 1216 * @param[in] call The message parameters. 1217 * @param[out] answer The message answer parameters. 1218 * @param[out] answer_count The last parameter for the actual answer in the 1219 * answer parameter. 1220 * @return EOK on success. 1221 * @return ENOTSUP if the message is not known. 1222 * 1223 * @see tcp_interface.h 1224 * @see IS_NET_TCP_MESSAGE() 1225 */ 1226 int tl_message(ipc_callid_t callid, ipc_call_t *call, 1227 ipc_call_t *answer, size_t *answer_count) 1228 { 1016 1229 assert(call); 1017 1230 assert(answer); … … 1019 1232 1020 1233 *answer_count = 0; 1021 switch(IPC_GET_METHOD(*call)){ 1022 case NET_TL_RECEIVED: 1023 //fibril_rwlock_read_lock(&tcp_globals.lock); 1024 if(! ERROR_OCCURRED(packet_translate_remote(tcp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 1025 ERROR_CODE = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP, IPC_GET_ERROR(call)); 1026 } 1027 //fibril_rwlock_read_unlock(&tcp_globals.lock); 1028 return ERROR_CODE; 1029 case IPC_M_CONNECT_TO_ME: 1030 return tcp_process_client_messages(callid, * call); 1031 } 1234 switch (IPC_GET_IMETHOD(*call)) { 1235 case IPC_M_CONNECT_TO_ME: 1236 return tcp_process_client_messages(callid, *call); 1237 } 1238 1032 1239 return ENOTSUP; 1033 1240 } 1034 1241 1035 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data){ 1242 void tcp_refresh_socket_data(tcp_socket_data_t *socket_data) 1243 { 1036 1244 assert(socket_data); 1037 1245 … … 1048 1256 } 1049 1257 1050 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data){ 1258 void tcp_initialize_socket_data(tcp_socket_data_t *socket_data) 1259 { 1051 1260 assert(socket_data); 1052 1261 … … 1057 1266 } 1058 1267 1059 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call){ 1268 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call) 1269 { 1060 1270 int res; 1061 1271 bool keep_on_going = true; 1062 1272 socket_cores_t local_sockets; 1063 int app_phone = IPC_GET_PHONE( &call);1064 struct sockaddr * 1273 int app_phone = IPC_GET_PHONE(call); 1274 struct sockaddr *addr; 1065 1275 int socket_id; 1066 1276 size_t addrlen; … … 1068 1278 fibril_rwlock_t lock; 1069 1279 ipc_call_t answer; 1070 int answer_count;1071 tcp_socket_data_ refsocket_data;1072 socket_core_ refsocket;1073 packet_dimension_ refpacket_dimension;1280 size_t answer_count; 1281 tcp_socket_data_t *socket_data; 1282 socket_core_t *socket; 1283 packet_dimension_t *packet_dimension; 1074 1284 1075 1285 /* … … 1083 1293 fibril_rwlock_initialize(&lock); 1084 1294 1085 while (keep_on_going){1086 1087 / / answer the call1295 while (keep_on_going) { 1296 1297 /* Answer the call */ 1088 1298 answer_call(callid, res, &answer, answer_count); 1089 1090 // refresh data 1299 /* Refresh data */ 1091 1300 refresh_answer(&answer, &answer_count); 1092 1093 // get the next call 1301 /* Get the next call */ 1094 1302 callid = async_get_call(&call); 1095 1303 1096 // process the call 1097 switch(IPC_GET_METHOD(call)){ 1098 case IPC_M_PHONE_HUNGUP: 1099 keep_on_going = false; 1100 res = EHANGUP; 1304 /* Process the call */ 1305 switch (IPC_GET_IMETHOD(call)) { 1306 case IPC_M_PHONE_HUNGUP: 1307 keep_on_going = false; 1308 res = EHANGUP; 1309 break; 1310 1311 case NET_SOCKET: 1312 socket_data = 1313 (tcp_socket_data_t *) malloc(sizeof(*socket_data)); 1314 if (!socket_data) { 1315 res = ENOMEM; 1101 1316 break; 1102 case NET_SOCKET: 1103 socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data)); 1104 if(! socket_data){ 1105 res = ENOMEM; 1106 }else{ 1107 tcp_initialize_socket_data(socket_data); 1108 socket_data->local_lock = &lock; 1109 socket_data->local_sockets = &local_sockets; 1110 fibril_rwlock_write_lock(&lock); 1111 socket_id = SOCKET_GET_SOCKET_ID(call); 1112 res = socket_create(&local_sockets, app_phone, socket_data, &socket_id); 1113 SOCKET_SET_SOCKET_ID(answer, socket_id); 1114 fibril_rwlock_write_unlock(&lock); 1115 if(res == EOK){ 1116 if (tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){ 1117 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size)); 1118 } 1119 // SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_TCP_FRAGMENT_SIZE); 1120 SOCKET_SET_HEADER_SIZE(answer, TCP_HEADER_SIZE); 1121 answer_count = 3; 1122 }else{ 1123 free(socket_data); 1124 } 1317 } 1318 1319 tcp_initialize_socket_data(socket_data); 1320 socket_data->local_lock = &lock; 1321 socket_data->local_sockets = &local_sockets; 1322 fibril_rwlock_write_lock(&lock); 1323 socket_id = SOCKET_GET_SOCKET_ID(call); 1324 res = socket_create(&local_sockets, app_phone, 1325 socket_data, &socket_id); 1326 SOCKET_SET_SOCKET_ID(answer, socket_id); 1327 fibril_rwlock_write_unlock(&lock); 1328 if (res != EOK) { 1329 free(socket_data); 1330 break; 1331 } 1332 if (tl_get_ip_packet_dimension(tcp_globals.ip_phone, 1333 &tcp_globals.dimensions, DEVICE_INVALID_ID, 1334 &packet_dimension) == EOK) { 1335 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, 1336 ((packet_dimension->content < 1337 socket_data->data_fragment_size) ? 1338 packet_dimension->content : 1339 socket_data->data_fragment_size)); 1340 } 1341 // SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_TCP_FRAGMENT_SIZE); 1342 SOCKET_SET_HEADER_SIZE(answer, TCP_HEADER_SIZE); 1343 answer_count = 3; 1344 break; 1345 1346 case NET_SOCKET_BIND: 1347 res = async_data_write_accept((void **) &addr, false, 1348 0, 0, 0, &addrlen); 1349 if (res != EOK) 1350 break; 1351 fibril_rwlock_write_lock(&tcp_globals.lock); 1352 fibril_rwlock_write_lock(&lock); 1353 res = socket_bind(&local_sockets, &tcp_globals.sockets, 1354 SOCKET_GET_SOCKET_ID(call), addr, addrlen, 1355 TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, 1356 tcp_globals.last_used_port); 1357 if (res == EOK) { 1358 socket = socket_cores_find(&local_sockets, 1359 SOCKET_GET_SOCKET_ID(call)); 1360 if (socket) { 1361 socket_data = (tcp_socket_data_t *) 1362 socket->specific_data; 1363 assert(socket_data); 1364 socket_data->state = TCP_SOCKET_LISTEN; 1125 1365 } 1366 } 1367 fibril_rwlock_write_unlock(&lock); 1368 fibril_rwlock_write_unlock(&tcp_globals.lock); 1369 free(addr); 1370 break; 1371 1372 case NET_SOCKET_LISTEN: 1373 fibril_rwlock_read_lock(&tcp_globals.lock); 1374 // fibril_rwlock_write_lock(&tcp_globals.lock); 1375 fibril_rwlock_write_lock(&lock); 1376 res = tcp_listen_message(&local_sockets, 1377 SOCKET_GET_SOCKET_ID(call), 1378 SOCKET_GET_BACKLOG(call)); 1379 fibril_rwlock_write_unlock(&lock); 1380 // fibril_rwlock_write_unlock(&tcp_globals.lock); 1381 fibril_rwlock_read_unlock(&tcp_globals.lock); 1382 break; 1383 1384 case NET_SOCKET_CONNECT: 1385 res = async_data_write_accept((void **) &addr, false, 1386 0, 0, 0, &addrlen); 1387 if (res != EOK) 1126 1388 break; 1127 case NET_SOCKET_BIND: 1128 res = data_receive((void **) &addr, &addrlen); 1129 if(res == EOK){ 1130 fibril_rwlock_write_lock(&tcp_globals.lock); 1131 fibril_rwlock_write_lock(&lock); 1132 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); 1133 if(res == EOK){ 1134 socket = socket_cores_find(&local_sockets, SOCKET_GET_SOCKET_ID(call)); 1135 if(socket){ 1136 socket_data = (tcp_socket_data_ref) socket->specific_data; 1137 assert(socket_data); 1138 socket_data->state = TCP_SOCKET_LISTEN; 1139 } 1140 } 1141 fibril_rwlock_write_unlock(&lock); 1142 fibril_rwlock_write_unlock(&tcp_globals.lock); 1143 free(addr); 1144 } 1145 break; 1146 case NET_SOCKET_LISTEN: 1147 fibril_rwlock_read_lock(&tcp_globals.lock); 1148 // fibril_rwlock_write_lock(&tcp_globals.lock); 1149 fibril_rwlock_write_lock(&lock); 1150 res = tcp_listen_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_BACKLOG(call)); 1389 /* 1390 * The global lock may be released in the 1391 * tcp_connect_message() function. 1392 */ 1393 fibril_rwlock_write_lock(&tcp_globals.lock); 1394 fibril_rwlock_write_lock(&lock); 1395 res = tcp_connect_message(&local_sockets, 1396 SOCKET_GET_SOCKET_ID(call), addr, addrlen); 1397 if (res != EOK) { 1151 1398 fibril_rwlock_write_unlock(&lock); 1152 // fibril_rwlock_write_unlock(&tcp_globals.lock); 1153 fibril_rwlock_read_unlock(&tcp_globals.lock); 1154 break; 1155 case NET_SOCKET_CONNECT: 1156 res = data_receive((void **) &addr, &addrlen); 1157 if(res == EOK){ 1158 // the global lock may be released in the tcp_connect_message() function 1159 fibril_rwlock_write_lock(&tcp_globals.lock); 1160 fibril_rwlock_write_lock(&lock); 1161 res = tcp_connect_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen); 1162 if(res != EOK){ 1163 fibril_rwlock_write_unlock(&lock); 1164 fibril_rwlock_write_unlock(&tcp_globals.lock); 1165 free(addr); 1166 } 1167 } 1168 break; 1169 case NET_SOCKET_ACCEPT: 1170 fibril_rwlock_read_lock(&tcp_globals.lock); 1171 fibril_rwlock_write_lock(&lock); 1172 res = tcp_accept_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_NEW_SOCKET_ID(call), &size, &addrlen); 1173 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size); 1399 fibril_rwlock_write_unlock(&tcp_globals.lock); 1400 free(addr); 1401 } 1402 break; 1403 1404 case NET_SOCKET_ACCEPT: 1405 fibril_rwlock_read_lock(&tcp_globals.lock); 1406 fibril_rwlock_write_lock(&lock); 1407 res = tcp_accept_message(&local_sockets, 1408 SOCKET_GET_SOCKET_ID(call), 1409 SOCKET_GET_NEW_SOCKET_ID(call), &size, &addrlen); 1410 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size); 1411 fibril_rwlock_write_unlock(&lock); 1412 fibril_rwlock_read_unlock(&tcp_globals.lock); 1413 if (res > 0) { 1414 SOCKET_SET_SOCKET_ID(answer, res); 1415 SOCKET_SET_ADDRESS_LENGTH(answer, addrlen); 1416 answer_count = 3; 1417 } 1418 break; 1419 1420 case NET_SOCKET_SEND: 1421 fibril_rwlock_read_lock(&tcp_globals.lock); 1422 fibril_rwlock_write_lock(&lock); 1423 res = tcp_send_message(&local_sockets, 1424 SOCKET_GET_SOCKET_ID(call), 1425 SOCKET_GET_DATA_FRAGMENTS(call), &size, 1426 SOCKET_GET_FLAGS(call)); 1427 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size); 1428 if (res != EOK) { 1174 1429 fibril_rwlock_write_unlock(&lock); 1175 1430 fibril_rwlock_read_unlock(&tcp_globals.lock); 1176 if(res > 0){ 1177 SOCKET_SET_SOCKET_ID(answer, res); 1178 SOCKET_SET_ADDRESS_LENGTH(answer, addrlen); 1179 answer_count = 3; 1180 } 1431 } else { 1432 answer_count = 2; 1433 } 1434 break; 1435 1436 case NET_SOCKET_SENDTO: 1437 res = async_data_write_accept((void **) &addr, false, 1438 0, 0, 0, &addrlen); 1439 if (res != EOK) 1181 1440 break; 1182 case NET_SOCKET_SEND: 1183 fibril_rwlock_read_lock(&tcp_globals.lock); 1184 fibril_rwlock_write_lock(&lock); 1185 res = tcp_send_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_DATA_FRAGMENTS(call), &size, SOCKET_GET_FLAGS(call)); 1186 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size); 1187 if(res != EOK){ 1188 fibril_rwlock_write_unlock(&lock); 1189 fibril_rwlock_read_unlock(&tcp_globals.lock); 1190 }else{ 1191 answer_count = 2; 1192 } 1193 break; 1194 case NET_SOCKET_SENDTO: 1195 res = data_receive((void **) &addr, &addrlen); 1196 if(res == EOK){ 1197 fibril_rwlock_read_lock(&tcp_globals.lock); 1198 fibril_rwlock_write_lock(&lock); 1199 res = tcp_send_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_DATA_FRAGMENTS(call), &size, SOCKET_GET_FLAGS(call)); 1200 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size); 1201 if(res != EOK){ 1202 fibril_rwlock_write_unlock(&lock); 1203 fibril_rwlock_read_unlock(&tcp_globals.lock); 1204 }else{ 1205 answer_count = 2; 1206 } 1207 free(addr); 1208 } 1209 break; 1210 case NET_SOCKET_RECV: 1211 fibril_rwlock_read_lock(&tcp_globals.lock); 1212 fibril_rwlock_write_lock(&lock); 1213 res = tcp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), NULL); 1441 fibril_rwlock_read_lock(&tcp_globals.lock); 1442 fibril_rwlock_write_lock(&lock); 1443 res = tcp_send_message(&local_sockets, 1444 SOCKET_GET_SOCKET_ID(call), 1445 SOCKET_GET_DATA_FRAGMENTS(call), &size, 1446 SOCKET_GET_FLAGS(call)); 1447 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size); 1448 if (res != EOK) { 1214 1449 fibril_rwlock_write_unlock(&lock); 1215 1450 fibril_rwlock_read_unlock(&tcp_globals.lock); 1216 if(res > 0){ 1217 SOCKET_SET_READ_DATA_LENGTH(answer, res); 1218 answer_count = 1; 1219 res = EOK; 1220 } 1221 break; 1222 case NET_SOCKET_RECVFROM: 1223 fibril_rwlock_read_lock(&tcp_globals.lock); 1224 fibril_rwlock_write_lock(&lock); 1225 res = tcp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen); 1451 } else { 1452 answer_count = 2; 1453 } 1454 free(addr); 1455 break; 1456 1457 case NET_SOCKET_RECV: 1458 fibril_rwlock_read_lock(&tcp_globals.lock); 1459 fibril_rwlock_write_lock(&lock); 1460 res = tcp_recvfrom_message(&local_sockets, 1461 SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), 1462 NULL); 1463 fibril_rwlock_write_unlock(&lock); 1464 fibril_rwlock_read_unlock(&tcp_globals.lock); 1465 if (res > 0) { 1466 SOCKET_SET_READ_DATA_LENGTH(answer, res); 1467 answer_count = 1; 1468 res = EOK; 1469 } 1470 break; 1471 1472 case NET_SOCKET_RECVFROM: 1473 fibril_rwlock_read_lock(&tcp_globals.lock); 1474 fibril_rwlock_write_lock(&lock); 1475 res = tcp_recvfrom_message(&local_sockets, 1476 SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), 1477 &addrlen); 1478 fibril_rwlock_write_unlock(&lock); 1479 fibril_rwlock_read_unlock(&tcp_globals.lock); 1480 if (res > 0) { 1481 SOCKET_SET_READ_DATA_LENGTH(answer, res); 1482 SOCKET_SET_ADDRESS_LENGTH(answer, addrlen); 1483 answer_count = 3; 1484 res = EOK; 1485 } 1486 break; 1487 1488 case NET_SOCKET_CLOSE: 1489 fibril_rwlock_write_lock(&tcp_globals.lock); 1490 fibril_rwlock_write_lock(&lock); 1491 res = tcp_close_message(&local_sockets, 1492 SOCKET_GET_SOCKET_ID(call)); 1493 if (res != EOK) { 1226 1494 fibril_rwlock_write_unlock(&lock); 1227 fibril_rwlock_read_unlock(&tcp_globals.lock); 1228 if(res > 0){ 1229 SOCKET_SET_READ_DATA_LENGTH(answer, res); 1230 SOCKET_SET_ADDRESS_LENGTH(answer, addrlen); 1231 answer_count = 3; 1232 res = EOK; 1233 } 1234 break; 1235 case NET_SOCKET_CLOSE: 1236 fibril_rwlock_write_lock(&tcp_globals.lock); 1237 fibril_rwlock_write_lock(&lock); 1238 res = tcp_close_message(&local_sockets, SOCKET_GET_SOCKET_ID(call)); 1239 if(res != EOK){ 1240 fibril_rwlock_write_unlock(&lock); 1241 fibril_rwlock_write_unlock(&tcp_globals.lock); 1242 } 1243 break; 1244 case NET_SOCKET_GETSOCKOPT: 1245 case NET_SOCKET_SETSOCKOPT: 1246 default: 1247 res = ENOTSUP; 1248 break; 1249 } 1250 } 1251 1252 // release the application phone 1253 ipc_hangup(app_phone); 1495 fibril_rwlock_write_unlock(&tcp_globals.lock); 1496 } 1497 break; 1498 1499 case NET_SOCKET_GETSOCKOPT: 1500 case NET_SOCKET_SETSOCKOPT: 1501 default: 1502 res = ENOTSUP; 1503 break; 1504 } 1505 } 1506 1507 /* Release the application phone */ 1508 async_hangup(app_phone); 1254 1509 1255 1510 printf("release\n"); 1256 // release all local sockets 1257 socket_cores_release(tcp_globals.net_phone, &local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 1511 /* Release all local sockets */ 1512 socket_cores_release(tcp_globals.net_phone, &local_sockets, 1513 &tcp_globals.sockets, tcp_free_socket_data); 1258 1514 1259 1515 return EOK; 1260 1516 } 1261 1517 1262 int tcp_timeout(void * data){ 1263 tcp_timeout_ref timeout = data; 1518 int tcp_timeout(void *data) 1519 { 1520 tcp_timeout_t *timeout = data; 1264 1521 int keep_write_lock = false; 1265 socket_core_ refsocket;1266 tcp_socket_data_ refsocket_data;1522 socket_core_t *socket; 1523 tcp_socket_data_t *socket_data; 1267 1524 1268 1525 assert(timeout); 1269 1526 1270 / / sleep the given timeout1527 /* Sleep the given timeout */ 1271 1528 async_usleep(timeout->timeout); 1272 / / lock the globals1273 if (timeout->globals_read_only){1529 /* Lock the globals */ 1530 if (timeout->globals_read_only) 1274 1531 fibril_rwlock_read_lock(&tcp_globals.lock); 1275 }else{1532 else 1276 1533 fibril_rwlock_write_lock(&tcp_globals.lock); 1277 } 1278 // find the pending operation socket 1279 socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length); 1280 if(socket && (socket->socket_id == timeout->socket_id)){ 1281 socket_data = (tcp_socket_data_ref) socket->specific_data; 1282 assert(socket_data); 1283 if(socket_data->local_sockets == timeout->local_sockets){ 1284 fibril_rwlock_write_lock(socket_data->local_lock); 1285 if(timeout->sequence_number){ 1286 // increase the timeout counter; 1287 ++ socket_data->timeout_count; 1288 if(socket_data->timeout_count == TCP_MAX_TIMEOUTS){ 1289 // TODO release as connection lost 1290 //tcp_refresh_socket_data(socket_data); 1291 fibril_rwlock_write_unlock(socket_data->local_lock); 1292 }else{ 1293 // retransmit 1294 // tcp_retransmit_packet(socket, socket_data, timeout->sequence_number); 1295 fibril_rwlock_write_unlock(socket_data->local_lock); 1296 } 1297 }else{ 1298 fibril_mutex_lock(&socket_data->operation.mutex); 1299 // set the timeout operation result if state not changed 1300 if(socket_data->state == timeout->state){ 1301 socket_data->operation.result = ETIMEOUT; 1302 // notify the main fibril 1303 fibril_condvar_signal(&socket_data->operation.condvar); 1304 // keep the global write lock 1305 keep_write_lock = true; 1306 }else{ 1307 // operation is ok, do nothing 1308 // unlocking from now on, so the unlock order does not matter... 1309 fibril_rwlock_write_unlock(socket_data->local_lock); 1310 } 1311 fibril_mutex_unlock(&socket_data->operation.mutex); 1312 } 1313 } 1314 } 1315 // unlock only if no socket 1316 if(timeout->globals_read_only){ 1534 1535 /* Find the pending operation socket */ 1536 socket = socket_port_find(&tcp_globals.sockets, timeout->port, 1537 timeout->key, timeout->key_length); 1538 if (!socket || (socket->socket_id != timeout->socket_id)) 1539 goto out; 1540 1541 socket_data = (tcp_socket_data_t *) socket->specific_data; 1542 assert(socket_data); 1543 if (socket_data->local_sockets != timeout->local_sockets) 1544 goto out; 1545 1546 fibril_rwlock_write_lock(socket_data->local_lock); 1547 if (timeout->sequence_number) { 1548 /* Increase the timeout counter */ 1549 socket_data->timeout_count++; 1550 if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) { 1551 /* TODO release as connection lost */ 1552 //tcp_refresh_socket_data(socket_data); 1553 fibril_rwlock_write_unlock(socket_data->local_lock); 1554 } else { 1555 /* Retransmit */ 1556 // tcp_retransmit_packet(socket, 1557 // socket_data, timeout->sequence_number); 1558 fibril_rwlock_write_unlock(socket_data->local_lock); 1559 } 1560 } else { 1561 fibril_mutex_lock(&socket_data->operation.mutex); 1562 /* Set the timeout operation result if state not changed */ 1563 if (socket_data->state == timeout->state) { 1564 socket_data->operation.result = ETIMEOUT; 1565 1566 /* Notify the main fibril */ 1567 fibril_condvar_signal(&socket_data->operation.condvar); 1568 1569 /* Keep the global write lock */ 1570 keep_write_lock = true; 1571 } else { 1572 /* 1573 * Operation is ok, do nothing. 1574 * Unlocking from now on, so the unlocking 1575 * order does not matter. 1576 */ 1577 fibril_rwlock_write_unlock(socket_data->local_lock); 1578 } 1579 fibril_mutex_unlock(&socket_data->operation.mutex); 1580 } 1581 1582 out: 1583 /* Unlock only if no socket */ 1584 if (timeout->globals_read_only) 1317 1585 fibril_rwlock_read_unlock(&tcp_globals.lock); 1318 }else if(! keep_write_lock){1319 / / release if not desired1586 else if (!keep_write_lock) 1587 /* Release if not desired */ 1320 1588 fibril_rwlock_write_unlock(&tcp_globals.lock); 1321 }1322 / / release the timeout structure1589 1590 /* Release the timeout structure */ 1323 1591 free(timeout); 1324 1592 return EOK; 1325 1593 } 1326 1594 1327 int tcp_release_after_timeout(void * data){ 1328 tcp_timeout_ref timeout = data; 1329 socket_core_ref socket; 1330 tcp_socket_data_ref socket_data; 1331 fibril_rwlock_t * local_lock; 1595 int tcp_release_after_timeout(void *data) 1596 { 1597 tcp_timeout_t *timeout = data; 1598 socket_core_t *socket; 1599 tcp_socket_data_t *socket_data; 1600 fibril_rwlock_t *local_lock; 1332 1601 1333 1602 assert(timeout); 1334 1603 1335 / / sleep the given timeout1604 /* Sleep the given timeout */ 1336 1605 async_usleep(timeout->timeout); 1337 // lock the globals 1606 1607 /* Lock the globals */ 1338 1608 fibril_rwlock_write_lock(&tcp_globals.lock); 1339 // find the pending operation socket 1340 socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length); 1341 if(socket && (socket->socket_id == timeout->socket_id)){ 1342 socket_data = (tcp_socket_data_ref) socket->specific_data; 1609 1610 /* Find the pending operation socket */ 1611 socket = socket_port_find(&tcp_globals.sockets, timeout->port, 1612 timeout->key, timeout->key_length); 1613 1614 if (socket && (socket->socket_id == timeout->socket_id)) { 1615 socket_data = (tcp_socket_data_t *) socket->specific_data; 1343 1616 assert(socket_data); 1344 if (socket_data->local_sockets == timeout->local_sockets){1617 if (socket_data->local_sockets == timeout->local_sockets) { 1345 1618 local_lock = socket_data->local_lock; 1346 1619 fibril_rwlock_write_lock(local_lock); 1347 socket_destroy(tcp_globals.net_phone, timeout->socket_id, timeout->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 1620 socket_destroy(tcp_globals.net_phone, 1621 timeout->socket_id, timeout->local_sockets, 1622 &tcp_globals.sockets, tcp_free_socket_data); 1348 1623 fibril_rwlock_write_unlock(local_lock); 1349 1624 } 1350 1625 } 1351 // unlock the globals 1626 1627 /* Unlock the globals */ 1352 1628 fibril_rwlock_write_unlock(&tcp_globals.lock); 1353 // release the timeout structure 1629 1630 /* Release the timeout structure */ 1354 1631 free(timeout); 1632 1355 1633 return EOK; 1356 1634 } 1357 1635 1358 void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number){ 1359 packet_t packet; 1360 packet_t copy; 1636 void tcp_retransmit_packet(socket_core_t *socket, tcp_socket_data_t * 1637 socket_data, size_t sequence_number) 1638 { 1639 packet_t *packet; 1640 packet_t *copy; 1361 1641 size_t data_length; 1362 1642 … … 1365 1645 assert(socket->specific_data == socket_data); 1366 1646 1367 / / sent packet?1647 /* Sent packet? */ 1368 1648 packet = pq_find(socket_data->outgoing, sequence_number); 1369 1649 printf("retransmit %d\n", packet_get_id(packet)); 1370 if (packet){1650 if (packet) { 1371 1651 pq_get_order(packet, NULL, &data_length); 1372 copy = tcp_prepare_copy(socket, socket_data, packet, data_length, sequence_number); 1652 copy = tcp_prepare_copy(socket, socket_data, packet, 1653 data_length, sequence_number); 1373 1654 fibril_rwlock_write_unlock(socket_data->local_lock); 1374 // 1375 if (copy){1655 // printf("r send %d\n", packet_get_id(packet)); 1656 if (copy) 1376 1657 tcp_send_packets(socket_data->device_id, copy); 1377 } 1378 }else{ 1658 } else { 1379 1659 fibril_rwlock_write_unlock(socket_data->local_lock); 1380 1660 } 1381 1661 } 1382 1662 1383 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog){ 1384 socket_core_ref socket; 1385 tcp_socket_data_ref socket_data; 1663 int tcp_listen_message(socket_cores_t *local_sockets, int socket_id, 1664 int backlog) 1665 { 1666 socket_core_t *socket; 1667 tcp_socket_data_t *socket_data; 1386 1668 1387 1669 assert(local_sockets); 1388 1670 1389 if (backlog < 0){1671 if (backlog < 0) 1390 1672 return EINVAL; 1391 } 1392 / / find the socket1673 1674 /* Find the socket */ 1393 1675 socket = socket_cores_find(local_sockets, socket_id); 1394 if (! socket){1676 if (!socket) 1395 1677 return ENOTSOCK; 1396 }1397 / / get the socket specific data1398 socket_data = (tcp_socket_data_ ref) socket->specific_data;1678 1679 /* Get the socket specific data */ 1680 socket_data = (tcp_socket_data_t *) socket->specific_data; 1399 1681 assert(socket_data); 1400 // set the backlog 1682 1683 /* Set the backlog */ 1401 1684 socket_data->backlog = backlog; 1685 1402 1686 return EOK; 1403 1687 } 1404 1688 1405 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen){ 1406 ERROR_DECLARE; 1407 1408 socket_core_ref socket; 1689 int tcp_connect_message(socket_cores_t *local_sockets, int socket_id, 1690 struct sockaddr *addr, socklen_t addrlen) 1691 { 1692 socket_core_t *socket; 1693 int rc; 1409 1694 1410 1695 assert(local_sockets); … … 1412 1697 assert(addrlen > 0); 1413 1698 1414 / / find the socket1699 /* Find the socket */ 1415 1700 socket = socket_cores_find(local_sockets, socket_id); 1416 if (! socket){1701 if (!socket) 1417 1702 return ENOTSOCK; 1418 } 1419 if(ERROR_OCCURRED(tcp_connect_core(socket, local_sockets, addr, addrlen))){ 1703 1704 rc = tcp_connect_core(socket, local_sockets, addr, addrlen); 1705 if (rc != EOK) { 1420 1706 tcp_free_socket_data(socket); 1421 // unbind if bound 1422 if(socket->port > 0){ 1423 socket_ports_exclude(&tcp_globals.sockets, socket->port); 1707 /* Unbind if bound */ 1708 if (socket->port > 0) { 1709 socket_ports_exclude(&tcp_globals.sockets, 1710 socket->port, free); 1424 1711 socket->port = 0; 1425 1712 } 1426 1713 } 1427 return ERROR_CODE; 1428 } 1429 1430 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen){ 1431 ERROR_DECLARE; 1432 1433 tcp_socket_data_ref socket_data; 1434 packet_t packet; 1714 return rc; 1715 } 1716 1717 int tcp_connect_core(socket_core_t *socket, socket_cores_t *local_sockets, 1718 struct sockaddr *addr, socklen_t addrlen) 1719 { 1720 tcp_socket_data_t *socket_data; 1721 packet_t *packet; 1722 int rc; 1435 1723 1436 1724 assert(socket); … … 1438 1726 assert(addrlen > 0); 1439 1727 1440 / / get the socket specific data1441 socket_data = (tcp_socket_data_ ref) socket->specific_data;1728 /* Get the socket specific data */ 1729 socket_data = (tcp_socket_data_t *) socket->specific_data; 1442 1730 assert(socket_data); 1443 1731 assert(socket->specific_data == socket_data); 1444 if((socket_data->state != TCP_SOCKET_INITIAL) 1445 && ((socket_data->state != TCP_SOCKET_LISTEN) || (socket->port <= 0))){ 1732 if ((socket_data->state != TCP_SOCKET_INITIAL) && 1733 ((socket_data->state != TCP_SOCKET_LISTEN) || 1734 (socket->port <= 0))) 1446 1735 return EINVAL; 1447 } 1448 // get the destination port 1449 ERROR_PROPAGATE(tl_get_address_port(addr, addrlen, &socket_data->dest_port)); 1450 if(socket->port <= 0){ 1451 // try to find a free port 1452 ERROR_PROPAGATE(socket_bind_free_port(&tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port)); 1453 // set the next port as the search starting port number 1736 1737 /* Get the destination port */ 1738 rc = tl_get_address_port(addr, addrlen, &socket_data->dest_port); 1739 if (rc != EOK) 1740 return rc; 1741 1742 if (socket->port <= 0) { 1743 /* Try to find a free port */ 1744 rc = socket_bind_free_port(&tcp_globals.sockets, socket, 1745 TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, 1746 tcp_globals.last_used_port); 1747 if (rc != EOK) 1748 return rc; 1749 /* Set the next port as the search starting port number */ 1454 1750 tcp_globals.last_used_port = socket->port; 1455 1751 } 1456 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)); 1457 1458 // create the notification packet 1459 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 1, 0)); 1460 1461 // unlock the globals and wait for an operation 1752 1753 rc = ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP, 1754 addr, addrlen, &socket_data->device_id, 1755 &socket_data->pseudo_header, &socket_data->headerlen); 1756 if (rc != EOK) 1757 return rc; 1758 1759 /* Create the notification packet */ 1760 rc = tcp_create_notification_packet(&packet, socket, socket_data, 1, 0); 1761 if (rc != EOK) 1762 return rc; 1763 1764 /* Unlock the globals and wait for an operation */ 1462 1765 fibril_rwlock_write_unlock(&tcp_globals.lock); 1463 1766 1464 1767 socket_data->addr = addr; 1465 1768 socket_data->addrlen = addrlen; 1466 // send the packet 1467 if(ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1)) 1468 || ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))){ 1769 1770 /* Send the packet */ 1771 1772 if (((rc = tcp_queue_packet(socket, socket_data, packet, 1)) != EOK) || 1773 ((rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data, 0, 1774 TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false)) != 1775 EOK)) { 1469 1776 socket_data->addr = NULL; 1470 1777 socket_data->addrlen = 0; 1471 1778 fibril_rwlock_write_lock(&tcp_globals.lock); 1472 } else{1779 } else { 1473 1780 packet = tcp_get_packets_to_send(socket, socket_data); 1474 if (packet){1781 if (packet) { 1475 1782 fibril_mutex_lock(&socket_data->operation.mutex); 1476 1783 fibril_rwlock_write_unlock(socket_data->local_lock); 1477 // send the packet 1784 1785 socket_data->state = TCP_SOCKET_SYN_SENT; 1786 1787 /* Send the packet */ 1478 1788 printf("connecting %d\n", packet_get_id(packet)); 1479 1789 tcp_send_packets(socket_data->device_id, packet); 1480 // wait for a reply 1481 fibril_condvar_wait(&socket_data->operation.condvar, &socket_data->operation.mutex); 1482 ERROR_CODE = socket_data->operation.result; 1483 if(ERROR_CODE != EOK){ 1790 1791 /* Wait for a reply */ 1792 fibril_condvar_wait(&socket_data->operation.condvar, 1793 &socket_data->operation.mutex); 1794 rc = socket_data->operation.result; 1795 if (rc != EOK) { 1484 1796 socket_data->addr = NULL; 1485 1797 socket_data->addrlen = 0; 1486 1798 } 1487 } else{1799 } else { 1488 1800 socket_data->addr = NULL; 1489 1801 socket_data->addrlen = 0; 1490 ERROR_CODE= EINTR;1802 rc = EINTR; 1491 1803 } 1492 1804 } 1493 1805 1494 1806 fibril_mutex_unlock(&socket_data->operation.mutex); 1495 1496 // return the result 1497 return ERROR_CODE; 1498 } 1499 1500 int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){ 1501 ERROR_DECLARE; 1502 1503 tcp_header_ref header; 1807 return rc; 1808 } 1809 1810 int tcp_queue_prepare_packet(socket_core_t *socket, 1811 tcp_socket_data_t *socket_data, packet_t *packet, size_t data_length) 1812 { 1813 tcp_header_t *header; 1814 int rc; 1504 1815 1505 1816 assert(socket); … … 1507 1818 assert(socket->specific_data == socket_data); 1508 1819 1509 / / get tcp header1510 header = (tcp_header_ ref) packet_get_data(packet);1511 if (! header){1820 /* Get TCP header */ 1821 header = (tcp_header_t *) packet_get_data(packet); 1822 if (!header) 1512 1823 return NO_DATA; 1513 }1824 1514 1825 header->destination_port = htons(socket_data->dest_port); 1515 1826 header->source_port = htons(socket->port); 1516 1827 header->sequence_number = htonl(socket_data->next_outgoing); 1517 if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr, socket_data->addrlen))){ 1828 1829 rc = packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr, 1830 socket_data->addrlen); 1831 if (rc != EOK) 1518 1832 return tcp_release_and_return(packet, EINVAL); 1519 } 1520 / / remember the outgoing FIN1521 if (header->finalize){1833 1834 /* Remember the outgoing FIN */ 1835 if (header->finalize) 1522 1836 socket_data->fin_outgoing = socket_data->next_outgoing; 1523 }1837 1524 1838 return EOK; 1525 1839 } 1526 1840 1527 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){ 1528 ERROR_DECLARE; 1841 int tcp_queue_packet(socket_core_t *socket, tcp_socket_data_t *socket_data, 1842 packet_t *packet, size_t data_length) 1843 { 1844 int rc; 1529 1845 1530 1846 assert(socket); … … 1532 1848 assert(socket->specific_data == socket_data); 1533 1849 1534 ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, data_length)); 1535 1536 if(ERROR_OCCURRED(pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing, data_length))){ 1537 return tcp_release_and_return(packet, ERROR_CODE); 1538 } 1850 rc = tcp_queue_prepare_packet(socket, socket_data, packet, data_length); 1851 if (rc != EOK) 1852 return rc; 1853 1854 rc = pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing, 1855 data_length); 1856 if (rc != EOK) 1857 return tcp_release_and_return(packet, rc); 1858 1539 1859 socket_data->next_outgoing += data_length; 1540 1860 return EOK; 1541 1861 } 1542 1862 1543 packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data){1544 ERROR_DECLARE; 1545 1546 packet_t packet;1547 packet_t copy;1548 packet_t sending = NULL;1549 packet_t previous = NULL;1863 packet_t *tcp_get_packets_to_send(socket_core_t *socket, tcp_socket_data_t * 1864 socket_data) 1865 { 1866 packet_t *packet; 1867 packet_t *copy; 1868 packet_t *sending = NULL; 1869 packet_t *previous = NULL; 1550 1870 size_t data_length; 1871 int rc; 1551 1872 1552 1873 assert(socket); … … 1555 1876 1556 1877 packet = pq_find(socket_data->outgoing, socket_data->last_outgoing + 1); 1557 while (packet){1878 while (packet) { 1558 1879 pq_get_order(packet, NULL, &data_length); 1559 // send only if fits into the window 1560 // respecting the possible overflow 1561 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))){ 1562 copy = tcp_prepare_copy(socket, socket_data, packet, data_length, socket_data->last_outgoing + 1); 1563 if(! copy){ 1880 1881 /* 1882 * Send only if fits into the window, respecting the possible 1883 * overflow. 1884 */ 1885 if (!IS_IN_INTERVAL_OVERFLOW( 1886 (uint32_t) socket_data->last_outgoing, 1887 (uint32_t) (socket_data->last_outgoing + data_length), 1888 (uint32_t) (socket_data->expected + socket_data->treshold))) 1889 break; 1890 1891 copy = tcp_prepare_copy(socket, socket_data, packet, 1892 data_length, socket_data->last_outgoing + 1); 1893 if (!copy) 1894 return sending; 1895 1896 if (!sending) { 1897 sending = copy; 1898 } else { 1899 rc = pq_insert_after(previous, copy); 1900 if (rc != EOK) { 1901 pq_release_remote(tcp_globals.net_phone, 1902 packet_get_id(copy)); 1564 1903 return sending; 1565 1904 } 1566 if(! sending){ 1567 sending = copy; 1568 }else{ 1569 if(ERROR_OCCURRED(pq_insert_after(previous, copy))){ 1570 pq_release_remote(tcp_globals.net_phone, packet_get_id(copy)); 1571 return sending; 1572 } 1573 } 1574 previous = copy; 1575 packet = pq_next(packet); 1576 // overflow occurred ? 1577 if((! packet) && (socket_data->last_outgoing > socket_data->next_outgoing)){ 1578 printf("gpts overflow\n"); 1579 // continue from the beginning 1580 packet = socket_data->outgoing; 1581 } 1582 socket_data->last_outgoing += data_length; 1583 }else{ 1584 break; 1585 } 1586 } 1905 } 1906 1907 previous = copy; 1908 packet = pq_next(packet); 1909 1910 /* Overflow occurred? */ 1911 if (!packet && 1912 (socket_data->last_outgoing > socket_data->next_outgoing)) { 1913 printf("gpts overflow\n"); 1914 /* Continue from the beginning */ 1915 packet = socket_data->outgoing; 1916 } 1917 socket_data->last_outgoing += data_length; 1918 } 1919 1587 1920 return sending; 1588 1921 } 1589 1922 1590 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){1591 ERROR_DECLARE; 1592 1593 tcp_header_ refheader;1923 packet_t *tcp_send_prepare_packet(socket_core_t *socket, tcp_socket_data_t * 1924 socket_data, packet_t *packet, size_t data_length, size_t sequence_number) 1925 { 1926 tcp_header_t *header; 1594 1927 uint32_t checksum; 1928 int rc; 1595 1929 1596 1930 assert(socket); … … 1598 1932 assert(socket->specific_data == socket_data); 1599 1933 1600 // adjust the pseudo header 1601 if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, packet_get_data_length(packet)))){ 1934 /* Adjust the pseudo header */ 1935 rc = ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, 1936 socket_data->headerlen, packet_get_data_length(packet)); 1937 if (rc != EOK) { 1602 1938 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1603 1939 return NULL; 1604 1940 } 1605 1941 1606 / / get the header1607 header = (tcp_header_ ref) packet_get_data(packet);1608 if (! header){1942 /* Get the header */ 1943 header = (tcp_header_t *) packet_get_data(packet); 1944 if (!header) { 1609 1945 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1610 1946 return NULL; … … 1612 1948 assert(ntohl(header->sequence_number) == sequence_number); 1613 1949 1614 // adjust the header 1615 if(socket_data->next_incoming){ 1616 header->acknowledgement_number = htonl(socket_data->next_incoming); 1950 /* Adjust the header */ 1951 if (socket_data->next_incoming) { 1952 header->acknowledgement_number = 1953 htonl(socket_data->next_incoming); 1617 1954 header->acknowledge = 1; 1618 1955 } 1619 1956 header->window = htons(socket_data->window); 1620 1957 1621 / / checksum1958 /* Checksum */ 1622 1959 header->checksum = 0; 1623 checksum = compute_checksum(0, socket_data->pseudo_header, socket_data->headerlen); 1624 checksum = compute_checksum(checksum, (uint8_t *) packet_get_data(packet), packet_get_data_length(packet)); 1960 checksum = compute_checksum(0, socket_data->pseudo_header, 1961 socket_data->headerlen); 1962 checksum = compute_checksum(checksum, 1963 (uint8_t *) packet_get_data(packet), 1964 packet_get_data_length(packet)); 1625 1965 header->checksum = htons(flip_checksum(compact_checksum(checksum))); 1626 // prepare the packet 1627 if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0))1628 // prepare the timeout1629 || ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, sequence_number, socket_data->state, socket_data->timeout, true))){1966 1967 /* Prepare the packet */ 1968 rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0); 1969 if (rc != EOK) { 1630 1970 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1631 1971 return NULL; 1632 1972 } 1973 1974 rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data, 1975 sequence_number, socket_data->state, socket_data->timeout, true); 1976 if (rc != EOK) { 1977 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1978 return NULL; 1979 } 1980 1633 1981 return packet; 1634 1982 } 1635 1983 1636 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){ 1637 packet_t copy; 1984 packet_t *tcp_prepare_copy(socket_core_t *socket, tcp_socket_data_t * 1985 socket_data, packet_t *packet, size_t data_length, size_t sequence_number) 1986 { 1987 packet_t *copy; 1638 1988 1639 1989 assert(socket); … … 1641 1991 assert(socket->specific_data == socket_data); 1642 1992 1643 / / make a copy of the packet1993 /* Make a copy of the packet */ 1644 1994 copy = packet_get_copy(tcp_globals.net_phone, packet); 1645 if (! copy){1995 if (!copy) 1646 1996 return NULL; 1647 } 1648 1649 return tcp_send_prepare_packet(socket, socket_data, copy, data_length, sequence_number); 1650 } 1651 1652 void tcp_send_packets(device_id_t device_id, packet_t packet){ 1653 packet_t next; 1654 1655 while(packet){ 1997 1998 return tcp_send_prepare_packet(socket, socket_data, copy, data_length, 1999 sequence_number); 2000 } 2001 2002 void tcp_send_packets(device_id_t device_id, packet_t *packet) 2003 { 2004 packet_t *next; 2005 2006 while (packet) { 1656 2007 next = pq_detach(packet); 1657 ip_send_msg(tcp_globals.ip_phone, device_id, packet, SERVICE_TCP, 0); 2008 ip_send_msg(tcp_globals.ip_phone, device_id, packet, 2009 SERVICE_TCP, 0); 1658 2010 packet = next; 1659 2011 } 1660 2012 } 1661 2013 1662 void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize){ 2014 void tcp_prepare_operation_header(socket_core_t *socket, 2015 tcp_socket_data_t *socket_data, tcp_header_t *header, int synchronize, 2016 int finalize) 2017 { 1663 2018 assert(socket); 1664 2019 assert(socket_data); … … 1674 2029 } 1675 2030 1676 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){ 1677 tcp_timeout_ref operation_timeout; 2031 int tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t), 2032 socket_core_t *socket, tcp_socket_data_t *socket_data, 2033 size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, 2034 int globals_read_only) 2035 { 2036 tcp_timeout_t *operation_timeout; 1678 2037 fid_t fibril; 1679 2038 … … 1682 2041 assert(socket->specific_data == socket_data); 1683 2042 1684 // prepare the timeout with key bundle structure 1685 operation_timeout = malloc(sizeof(*operation_timeout) + socket->key_length + 1); 1686 if(! operation_timeout){ 2043 /* Prepare the timeout with key bundle structure */ 2044 operation_timeout = malloc(sizeof(*operation_timeout) + 2045 socket->key_length + 1); 2046 if (!operation_timeout) 1687 2047 return ENOMEM; 1688 } 2048 1689 2049 bzero(operation_timeout, sizeof(*operation_timeout)); 1690 2050 operation_timeout->globals_read_only = globals_read_only; … … 1696 2056 operation_timeout->state = state; 1697 2057 1698 // copy the key 1699 operation_timeout->key = ((char *) operation_timeout) + sizeof(*operation_timeout); 2058 /* Copy the key */ 2059 operation_timeout->key = ((uint8_t *) operation_timeout) + 2060 sizeof(*operation_timeout); 1700 2061 operation_timeout->key_length = socket->key_length; 1701 2062 memcpy(operation_timeout->key, socket->key, socket->key_length); 1702 2063 operation_timeout->key[operation_timeout->key_length] = '\0'; 1703 2064 1704 / / prepare the timeouting thread2065 /* Prepare the timeouting thread */ 1705 2066 fibril = fibril_create(timeout_function, operation_timeout); 1706 if (! fibril){2067 if (!fibril) { 1707 2068 free(operation_timeout); 1708 return EPARTY; 1709 } 1710 // fibril_mutex_lock(&socket_data->operation.mutex); 1711 // start the timeouting fibril 2069 return ENOMEM; 2070 } 2071 2072 // fibril_mutex_lock(&socket_data->operation.mutex); 2073 /* Start the timeout fibril */ 1712 2074 fibril_add_ready(fibril); 1713 2075 //socket_data->state = state; … … 1715 2077 } 1716 2078 1717 int tcp_recvfrom_message(socket_cores_ ref local_sockets, int socket_id, int flags, size_t * addrlen){1718 ERROR_DECLARE; 1719 1720 socket_core_ refsocket;1721 tcp_socket_data_ refsocket_data;2079 int tcp_recvfrom_message(socket_cores_t *local_sockets, int socket_id, 2080 int flags, size_t *addrlen) 2081 { 2082 socket_core_t *socket; 2083 tcp_socket_data_t *socket_data; 1722 2084 int packet_id; 1723 packet_t packet;2085 packet_t *packet; 1724 2086 size_t length; 2087 int rc; 1725 2088 1726 2089 assert(local_sockets); 1727 2090 1728 / / find the socket2091 /* Find the socket */ 1729 2092 socket = socket_cores_find(local_sockets, socket_id); 1730 if (! socket){2093 if (!socket) 1731 2094 return ENOTSOCK; 1732 } 1733 / / get the socket specific data1734 if (! socket->specific_data){2095 2096 /* Get the socket specific data */ 2097 if (!socket->specific_data) 1735 2098 return NO_DATA; 1736 } 1737 socket_data = (tcp_socket_data_ref) socket->specific_data; 1738 1739 // check state 1740 if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){ 2099 2100 socket_data = (tcp_socket_data_t *) socket->specific_data; 2101 2102 /* Check state */ 2103 if ((socket_data->state != TCP_SOCKET_ESTABLISHED) && 2104 (socket_data->state != TCP_SOCKET_CLOSE_WAIT)) 1741 2105 return ENOTCONN; 1742 } 1743 1744 // send the source address if desired 1745 if(addrlen){ 1746 ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen)); 2106 2107 /* Send the source address if desired */ 2108 if (addrlen) { 2109 rc = data_reply(socket_data->addr, socket_data->addrlen); 2110 if (rc != EOK) 2111 return rc; 1747 2112 *addrlen = socket_data->addrlen; 1748 2113 } 1749 2114 1750 / / get the next received packet2115 /* Get the next received packet */ 1751 2116 packet_id = dyn_fifo_value(&socket->received); 1752 if (packet_id < 0){2117 if (packet_id < 0) 1753 2118 return NO_DATA; 1754 } 1755 ERROR_PROPAGATE(packet_translate_remote(tcp_globals.net_phone, &packet, packet_id)); 1756 1757 // reply the packets 1758 ERROR_PROPAGATE(socket_reply_packets(packet, &length)); 1759 1760 // release the packet 2119 2120 rc = packet_translate_remote(tcp_globals.net_phone, &packet, packet_id); 2121 if (rc != EOK) 2122 return rc; 2123 2124 /* Reply the packets */ 2125 rc = socket_reply_packets(packet, &length); 2126 if (rc != EOK) 2127 return rc; 2128 2129 /* Release the packet */ 1761 2130 dyn_fifo_pop(&socket->received); 1762 2131 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1763 // return the total length 2132 2133 /* Return the total length */ 1764 2134 return (int) length; 1765 2135 } 1766 2136 1767 int tcp_send_message(socket_cores_ ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags){1768 ERROR_DECLARE; 1769 1770 socket_core_ refsocket;1771 tcp_socket_data_ refsocket_data;1772 packet_dimension_ refpacket_dimension;1773 packet_t packet;2137 int tcp_send_message(socket_cores_t *local_sockets, int socket_id, 2138 int fragments, size_t *data_fragment_size, int flags) 2139 { 2140 socket_core_t *socket; 2141 tcp_socket_data_t *socket_data; 2142 packet_dimension_t *packet_dimension; 2143 packet_t *packet; 1774 2144 size_t total_length; 1775 tcp_header_ refheader;2145 tcp_header_t *header; 1776 2146 int index; 1777 2147 int result; 2148 int rc; 1778 2149 1779 2150 assert(local_sockets); 1780 2151 assert(data_fragment_size); 1781 2152 1782 / / find the socket2153 /* Find the socket */ 1783 2154 socket = socket_cores_find(local_sockets, socket_id); 1784 if (! socket){2155 if (!socket) 1785 2156 return ENOTSOCK; 1786 } 1787 / / get the socket specific data1788 if (! socket->specific_data){2157 2158 /* Get the socket specific data */ 2159 if (!socket->specific_data) 1789 2160 return NO_DATA; 1790 } 1791 socket_data = (tcp_socket_data_ref) socket->specific_data; 1792 1793 // check state 1794 if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){ 2161 2162 socket_data = (tcp_socket_data_t *) socket->specific_data; 2163 2164 /* Check state */ 2165 if ((socket_data->state != TCP_SOCKET_ESTABLISHED) && 2166 (socket_data->state != TCP_SOCKET_CLOSE_WAIT)) 1795 2167 return ENOTCONN; 1796 } 1797 1798 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 1799 1800 *data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size); 1801 1802 for(index = 0; index < fragments; ++ index){ 1803 // read the data fragment 1804 result = tl_socket_read_packet_data(tcp_globals.net_phone, &packet, TCP_HEADER_SIZE, packet_dimension, socket_data->addr, socket_data->addrlen); 1805 if(result < 0){ 2168 2169 rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone, 2170 &tcp_globals.dimensions, socket_data->device_id, &packet_dimension); 2171 if (rc != EOK) 2172 return rc; 2173 2174 *data_fragment_size = 2175 ((packet_dimension->content < socket_data->data_fragment_size) ? 2176 packet_dimension->content : socket_data->data_fragment_size); 2177 2178 for (index = 0; index < fragments; index++) { 2179 /* Read the data fragment */ 2180 result = tl_socket_read_packet_data(tcp_globals.net_phone, 2181 &packet, TCP_HEADER_SIZE, packet_dimension, 2182 socket_data->addr, socket_data->addrlen); 2183 if (result < 0) 1806 2184 return result; 1807 } 2185 1808 2186 total_length = (size_t) result; 1809 // prefix the tcp header 2187 2188 /* Prefix the TCP header */ 1810 2189 header = PACKET_PREFIX(packet, tcp_header_t); 1811 if (! header){2190 if (!header) 1812 2191 return tcp_release_and_return(packet, ENOMEM); 1813 } 2192 1814 2193 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); 1815 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 0)); 1816 } 1817 1818 // flush packets 2194 rc = tcp_queue_packet(socket, socket_data, packet, total_length); 2195 if (rc != EOK) 2196 return rc; 2197 } 2198 2199 /* Flush packets */ 1819 2200 packet = tcp_get_packets_to_send(socket, socket_data); 1820 2201 fibril_rwlock_write_unlock(socket_data->local_lock); 1821 2202 fibril_rwlock_read_unlock(&tcp_globals.lock); 1822 if(packet){ 1823 // send the packet 2203 2204 if (packet) { 2205 /* Send the packet */ 1824 2206 tcp_send_packets(socket_data->device_id, packet); 1825 2207 } … … 1828 2210 } 1829 2211 1830 int tcp_close_message(socket_cores_ref local_sockets, int socket_id){ 1831 ERROR_DECLARE; 1832 1833 socket_core_ref socket; 1834 tcp_socket_data_ref socket_data; 1835 packet_t packet; 1836 1837 // find the socket 2212 int 2213 tcp_close_message(socket_cores_t *local_sockets, int socket_id) 2214 { 2215 socket_core_t *socket; 2216 tcp_socket_data_t *socket_data; 2217 packet_t *packet; 2218 int rc; 2219 2220 /* Find the socket */ 1838 2221 socket = socket_cores_find(local_sockets, socket_id); 1839 if (! socket){2222 if (!socket) 1840 2223 return ENOTSOCK; 1841 } 1842 / / get the socket specific data1843 socket_data = (tcp_socket_data_ ref) socket->specific_data;2224 2225 /* Get the socket specific data */ 2226 socket_data = (tcp_socket_data_t *) socket->specific_data; 1844 2227 assert(socket_data); 1845 2228 1846 // check state 1847 switch(socket_data->state){ 1848 case TCP_SOCKET_ESTABLISHED: 1849 socket_data->state = TCP_SOCKET_FIN_WAIT_1; 1850 break; 1851 case TCP_SOCKET_CLOSE_WAIT: 1852 socket_data->state = TCP_SOCKET_LAST_ACK; 1853 break; 1854 // case TCP_SOCKET_LISTEN: 1855 default: 1856 // just destroy 1857 if(! ERROR_OCCURRED(socket_destroy(tcp_globals.net_phone, socket_id, local_sockets, &tcp_globals.sockets, tcp_free_socket_data))){ 1858 fibril_rwlock_write_unlock(socket_data->local_lock); 1859 fibril_rwlock_write_unlock(&tcp_globals.lock); 1860 } 1861 return ERROR_CODE; 1862 } 1863 // send FIN 1864 // TODO should I wait to complete? 1865 1866 // create the notification packet 1867 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1)); 1868 1869 // send the packet 1870 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1)); 1871 1872 // flush packets 2229 /* Check state */ 2230 switch (socket_data->state) { 2231 case TCP_SOCKET_ESTABLISHED: 2232 socket_data->state = TCP_SOCKET_FIN_WAIT_1; 2233 break; 2234 2235 case TCP_SOCKET_CLOSE_WAIT: 2236 socket_data->state = TCP_SOCKET_LAST_ACK; 2237 break; 2238 2239 // case TCP_SOCKET_LISTEN: 2240 2241 default: 2242 /* Just destroy */ 2243 rc = socket_destroy(tcp_globals.net_phone, socket_id, 2244 local_sockets, &tcp_globals.sockets, 2245 tcp_free_socket_data); 2246 if (rc == EOK) { 2247 fibril_rwlock_write_unlock(socket_data->local_lock); 2248 fibril_rwlock_write_unlock(&tcp_globals.lock); 2249 } 2250 return rc; 2251 } 2252 2253 /* 2254 * Send FIN. 2255 * TODO should I wait to complete? 2256 */ 2257 2258 /* Create the notification packet */ 2259 rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1); 2260 if (rc != EOK) 2261 return rc; 2262 2263 /* Send the packet */ 2264 rc = tcp_queue_packet(socket, socket_data, packet, 1); 2265 if (rc != EOK) 2266 return rc; 2267 2268 /* Flush packets */ 1873 2269 packet = tcp_get_packets_to_send(socket, socket_data); 1874 2270 fibril_rwlock_write_unlock(socket_data->local_lock); 1875 2271 fibril_rwlock_write_unlock(&tcp_globals.lock); 1876 if(packet){ 1877 // send the packet 2272 2273 if (packet) { 2274 /* Send the packet */ 1878 2275 tcp_send_packets(socket_data->device_id, packet); 1879 2276 } 2277 1880 2278 return EOK; 1881 2279 } 1882 2280 1883 int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize){ 1884 ERROR_DECLARE; 1885 1886 packet_dimension_ref packet_dimension; 1887 tcp_header_ref header; 2281 int tcp_create_notification_packet(packet_t **packet, socket_core_t *socket, 2282 tcp_socket_data_t *socket_data, int synchronize, int finalize) 2283 { 2284 packet_dimension_t *packet_dimension; 2285 tcp_header_t *header; 2286 int rc; 1888 2287 1889 2288 assert(packet); 1890 2289 1891 // get the device packet dimension 1892 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 1893 // get a new packet 1894 *packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix); 1895 if(! * packet){ 2290 /* Get the device packet dimension */ 2291 rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone, 2292 &tcp_globals.dimensions, socket_data->device_id, &packet_dimension); 2293 if (rc != EOK) 2294 return rc; 2295 2296 /* Get a new packet */ 2297 *packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE, 2298 packet_dimension->addr_len, packet_dimension->prefix, 2299 packet_dimension->suffix); 2300 2301 if (!*packet) 1896 2302 return ENOMEM; 1897 } 1898 / / allocate space in the packet2303 2304 /* Allocate space in the packet */ 1899 2305 header = PACKET_SUFFIX(*packet, tcp_header_t); 1900 if (! header){2306 if (!header) 1901 2307 tcp_release_and_return(*packet, ENOMEM); 1902 } 1903 1904 tcp_prepare_operation_header(socket, socket_data, header, synchronize, finalize); 2308 2309 tcp_prepare_operation_header(socket, socket_data, header, synchronize, 2310 finalize); 2311 1905 2312 return EOK; 1906 2313 } 1907 2314 1908 int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen){ 1909 ERROR_DECLARE; 1910 1911 socket_core_ref accepted; 1912 socket_core_ref socket; 1913 tcp_socket_data_ref socket_data; 1914 packet_dimension_ref packet_dimension; 2315 int tcp_accept_message(socket_cores_t *local_sockets, int socket_id, 2316 int new_socket_id, size_t *data_fragment_size, size_t *addrlen) 2317 { 2318 socket_core_t *accepted; 2319 socket_core_t *socket; 2320 tcp_socket_data_t *socket_data; 2321 packet_dimension_t *packet_dimension; 2322 int rc; 1915 2323 1916 2324 assert(local_sockets); … … 1918 2326 assert(addrlen); 1919 2327 1920 / / find the socket2328 /* Find the socket */ 1921 2329 socket = socket_cores_find(local_sockets, socket_id); 1922 if (! socket){2330 if (!socket) 1923 2331 return ENOTSOCK; 1924 } 1925 / / get the socket specific data1926 socket_data = (tcp_socket_data_ ref) socket->specific_data;2332 2333 /* Get the socket specific data */ 2334 socket_data = (tcp_socket_data_t *) socket->specific_data; 1927 2335 assert(socket_data); 1928 2336 1929 / / check state1930 if (socket_data->state != TCP_SOCKET_LISTEN){2337 /* Check state */ 2338 if (socket_data->state != TCP_SOCKET_LISTEN) 1931 2339 return EINVAL; 1932 } 1933 1934 do{ 2340 2341 do { 1935 2342 socket_id = dyn_fifo_value(&socket->accepted); 1936 if (socket_id < 0){2343 if (socket_id < 0) 1937 2344 return ENOTSOCK; 1938 }1939 2345 socket_id *= -1; 1940 2346 1941 2347 accepted = socket_cores_find(local_sockets, socket_id); 1942 if (! accepted){2348 if (!accepted) 1943 2349 return ENOTSOCK; 1944 } 1945 / / get the socket specific data1946 socket_data = (tcp_socket_data_ ref) accepted->specific_data;2350 2351 /* Get the socket specific data */ 2352 socket_data = (tcp_socket_data_t *) accepted->specific_data; 1947 2353 assert(socket_data); 1948 // TODO can it be in another state? 1949 if(socket_data->state == TCP_SOCKET_ESTABLISHED){ 1950 ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen)); 1951 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 2354 /* TODO can it be in another state? */ 2355 if (socket_data->state == TCP_SOCKET_ESTABLISHED) { 2356 rc = data_reply(socket_data->addr, 2357 socket_data->addrlen); 2358 if (rc != EOK) 2359 return rc; 2360 rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone, 2361 &tcp_globals.dimensions, socket_data->device_id, 2362 &packet_dimension); 2363 if (rc != EOK) 2364 return rc; 1952 2365 *addrlen = socket_data->addrlen; 1953 *data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size); 1954 if(new_socket_id > 0){ 1955 ERROR_PROPAGATE(socket_cores_update(local_sockets, accepted->socket_id, new_socket_id)); 2366 2367 *data_fragment_size = 2368 ((packet_dimension->content < 2369 socket_data->data_fragment_size) ? 2370 packet_dimension->content : 2371 socket_data->data_fragment_size); 2372 2373 if (new_socket_id > 0) { 2374 rc = socket_cores_update(local_sockets, 2375 accepted->socket_id, new_socket_id); 2376 if (rc != EOK) 2377 return rc; 1956 2378 accepted->socket_id = new_socket_id; 1957 2379 } 1958 2380 } 1959 2381 dyn_fifo_pop(&socket->accepted); 1960 }while(socket_data->state != TCP_SOCKET_ESTABLISHED); 2382 } while (socket_data->state != TCP_SOCKET_ESTABLISHED); 2383 1961 2384 printf("ret accept %d\n", accepted->socket_id); 1962 2385 return accepted->socket_id; 1963 2386 } 1964 2387 1965 void tcp_free_socket_data(socket_core_ref socket){ 1966 tcp_socket_data_ref socket_data; 2388 void tcp_free_socket_data(socket_core_t *socket) 2389 { 2390 tcp_socket_data_t *socket_data; 1967 2391 1968 2392 assert(socket); … … 1970 2394 printf("destroy_socket %d\n", socket->socket_id); 1971 2395 1972 / / get the socket specific data1973 socket_data = (tcp_socket_data_ ref) socket->specific_data;2396 /* Get the socket specific data */ 2397 socket_data = (tcp_socket_data_t *) socket->specific_data; 1974 2398 assert(socket_data); 1975 //free the pseudo header 1976 if(socket_data->pseudo_header){ 1977 if(socket_data->headerlen){ 2399 2400 /* Free the pseudo header */ 2401 if (socket_data->pseudo_header) { 2402 if (socket_data->headerlen) { 1978 2403 printf("d pseudo\n"); 1979 2404 free(socket_data->pseudo_header); … … 1982 2407 socket_data->pseudo_header = NULL; 1983 2408 } 2409 1984 2410 socket_data->headerlen = 0; 1985 // free the address 1986 if(socket_data->addr){ 1987 if(socket_data->addrlen){ 2411 2412 /* Free the address */ 2413 if (socket_data->addr) { 2414 if (socket_data->addrlen) { 1988 2415 printf("d addr\n"); 1989 2416 free(socket_data->addr); … … 1995 2422 } 1996 2423 1997 int tcp_release_and_return(packet_t packet, int result){ 2424 /** Releases the packet and returns the result. 2425 * 2426 * @param[in] packet The packet queue to be released. 2427 * @param[in] result The result to be returned. 2428 * @return The result parameter. 2429 */ 2430 int tcp_release_and_return(packet_t *packet, int result) 2431 { 1998 2432 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1999 2433 return result; 2000 2434 } 2001 2435 2002 /** Default thread for new connections.2436 /** Process IPC messages from the IP module 2003 2437 * 2004 * @param[in] iid The initial message identifier.2005 * @param[in] icall The initial message call structure.2438 * @param[in] iid Message identifier. 2439 * @param[in,out] icall Message parameters. 2006 2440 * 2007 2441 */ 2008 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall) 2009 { 2010 /* 2011 * Accept the connection 2012 * - Answer the first IPC_M_CONNECT_ME_TO call. 2013 */ 2014 ipc_answer_0(iid, EOK); 2442 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall) 2443 { 2444 packet_t *packet; 2445 int rc; 2015 2446 2016 while(true) { 2017 ipc_call_t answer; 2018 int answer_count; 2447 while (true) { 2448 switch (IPC_GET_IMETHOD(*icall)) { 2449 case NET_TL_RECEIVED: 2450 rc = packet_translate_remote(tcp_globals.net_phone, &packet, 2451 IPC_GET_PACKET(*icall)); 2452 if (rc == EOK) 2453 rc = tcp_received_msg(IPC_GET_DEVICE(*icall), packet, 2454 SERVICE_TCP, IPC_GET_ERROR(*icall)); 2455 2456 async_answer_0(iid, (sysarg_t) rc); 2457 break; 2458 default: 2459 async_answer_0(iid, (sysarg_t) ENOTSUP); 2460 } 2019 2461 2020 /* Clear the answer structure */ 2021 refresh_answer(&answer, &answer_count); 2022 2023 /* Fetch the next message */ 2024 ipc_call_t call; 2025 ipc_callid_t callid = async_get_call(&call); 2026 2027 /* Process the message */ 2028 int res = tl_module_message_standalone(callid, &call, &answer, 2029 &answer_count); 2030 2031 /* End if said to either by the message or the processing result */ 2032 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP)) 2033 return; 2034 2035 /* Answer the message */ 2036 answer_call(callid, res, &answer, answer_count); 2037 } 2038 } 2039 2040 /** Starts the module. 2462 iid = async_get_call(icall); 2463 } 2464 } 2465 2466 /** Initialize the TCP module. 2041 2467 * 2042 * @param argc The count of the command line arguments. Ignored parameter. 2043 * @param argv The command line parameters. Ignored parameter. 2468 * @param[in] net_phone Network module phone. 2044 2469 * 2045 * @returnsEOK on success.2046 * @returns Other error codes as defined for each specific module start function.2470 * @return EOK on success. 2471 * @return ENOMEM if there is not enough memory left. 2047 2472 * 2048 2473 */ 2474 int tl_initialize(int net_phone) 2475 { 2476 fibril_rwlock_initialize(&tcp_globals.lock); 2477 fibril_rwlock_write_lock(&tcp_globals.lock); 2478 2479 tcp_globals.net_phone = net_phone; 2480 2481 tcp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT); 2482 tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, 2483 SERVICE_TCP, tcp_receiver); 2484 if (tcp_globals.ip_phone < 0) { 2485 fibril_rwlock_write_unlock(&tcp_globals.lock); 2486 return tcp_globals.ip_phone; 2487 } 2488 2489 int rc = socket_ports_initialize(&tcp_globals.sockets); 2490 if (rc != EOK) 2491 goto out; 2492 2493 rc = packet_dimensions_initialize(&tcp_globals.dimensions); 2494 if (rc != EOK) { 2495 socket_ports_destroy(&tcp_globals.sockets, free); 2496 goto out; 2497 } 2498 2499 tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1; 2500 2501 out: 2502 fibril_rwlock_write_unlock(&tcp_globals.lock); 2503 return rc; 2504 } 2505 2049 2506 int main(int argc, char *argv[]) 2050 2507 { 2051 ERROR_DECLARE; 2052 2053 /* Start the module */ 2054 if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection))) 2055 return ERROR_CODE; 2056 2057 return EOK; 2508 return tl_module_start(SERVICE_TCP); 2058 2509 } 2059 2510
Note:
See TracChangeset
for help on using the changeset viewer.