Changeset 89c57b6 in mainline for uspace/srv/net/tl/tcp/tcp.c


Ignore:
Timestamp:
2011-04-13T14:45:41Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
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.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/tcp/tcp.c

    rcefb126 r89c57b6  
    2828
    2929/** @addtogroup tcp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  TCP module implementation.
    35  *  @see tcp.h
     34 * TCP module implementation.
     35 * @see tcp.h
    3636 */
    3737
     
    4040#include <fibril_synch.h>
    4141#include <malloc.h>
    42 //TODO remove stdio
     42/* TODO remove stdio */
    4343#include <stdio.h>
    44 
    45 #include <ipc/ipc.h>
     44#include <errno.h>
     45
    4646#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
    5158#include <adt/dynamic_fifo.h>
    52 #include <packet/packet_client.h>
     59#include <packet_client.h>
    5360#include <packet_remote.h>
    5461#include <net_checksum.h>
    55 #include <in.h>
    56 #include <in6.h>
    57 #include <inet.h>
    5862#include <ip_client.h>
    5963#include <ip_interface.h>
    60 #include <ip_protocols.h>
    6164#include <icmp_client.h>
    62 #include <icmp_interface.h>
     65#include <icmp_remote.h>
    6366#include <net_interface.h>
    64 #include <socket_codes.h>
    65 #include <socket_errno.h>
    66 #include <tcp_codes.h>
    6767#include <socket_core.h>
    68 #include <socket_messages.h>
    6968#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>
    7371
    7472#include "tcp.h"
    7573#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.
    79116 */
    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))))
    129121
    130122/** Type definition of the TCP timeout.
    131123 *  @see tcp_timeout
    132124 */
    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;
     125typedef struct tcp_timeout tcp_timeout_t;
    139126
    140127/** TCP reply timeout data.
     
    142129 *  @see tcp_timeout()
    143130 */
    144 struct tcp_timeout{
    145         /** TCP global data are going to be read only.
    146          */
     131struct tcp_timeout {
     132        /** TCP global data are going to be read only. */
    147133        int globals_read_only;
    148         /** Socket port.
    149         */
     134
     135        /** Socket port. */
    150136        int port;
    151         /** Local sockets.
    152         */
    153         socket_cores_ref local_sockets;
    154         /** Socket identifier.
    155         */
     137
     138        /** Local sockets. */
     139        socket_cores_t *local_sockets;
     140
     141        /** Socket identifier. */
    156142        int socket_id;
    157         /** Socket state.
    158         */
     143
     144        /** Socket state. */
    159145        tcp_socket_state_t state;
    160         /** Sent packet sequence number.
    161         */
     146
     147        /** Sent packet sequence number. */
    162148        int sequence_number;
    163         /** Timeout in microseconds.
    164         */
     149
     150        /** Timeout in microseconds. */
    165151        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. */
    171157        size_t key_length;
    172158};
    173159
    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);
     160static int tcp_release_and_return(packet_t *, int);
     161static void tcp_prepare_operation_header(socket_core_t *, tcp_socket_data_t *,
     162    tcp_header_t *, int synchronize, int);
     163static int tcp_prepare_timeout(int (*)(void *), socket_core_t *,
     164    tcp_socket_data_t *, size_t, tcp_socket_state_t, suseconds_t, int);
     165static void tcp_free_socket_data(socket_core_t *);
     166
     167static int tcp_timeout(void *);
     168
     169static int tcp_release_after_timeout(void *);
     170
     171static int tcp_process_packet(device_id_t, packet_t *, services_t);
     172static int tcp_connect_core(socket_core_t *, socket_cores_t *,
     173    struct sockaddr *, socklen_t);
     174static int tcp_queue_prepare_packet(socket_core_t *, tcp_socket_data_t *,
     175    packet_t *, size_t);
     176static int tcp_queue_packet(socket_core_t *, tcp_socket_data_t *, packet_t *,
     177    size_t);
     178static packet_t *tcp_get_packets_to_send(socket_core_t *, tcp_socket_data_t *);
     179static void tcp_send_packets(device_id_t, packet_t *);
     180
     181static void tcp_process_acknowledgement(socket_core_t *, tcp_socket_data_t *,
     182    tcp_header_t *);
     183static packet_t *tcp_send_prepare_packet(socket_core_t *, tcp_socket_data_t *,
     184    packet_t *, size_t, size_t);
     185static 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);
     189static int tcp_create_notification_packet(packet_t **, socket_core_t *,
     190    tcp_socket_data_t *, int, int);
     191static void tcp_refresh_socket_data(tcp_socket_data_t *);
     192
     193static void tcp_initialize_socket_data(tcp_socket_data_t *);
     194
     195static int tcp_process_listen(socket_core_t *, tcp_socket_data_t *,
     196    tcp_header_t *, packet_t *, struct sockaddr *, struct sockaddr *, size_t);
     197static int tcp_process_syn_sent(socket_core_t *, tcp_socket_data_t *,
     198    tcp_header_t *, packet_t *);
     199static int tcp_process_syn_received(socket_core_t *, tcp_socket_data_t *,
     200    tcp_header_t *, packet_t *);
     201static int tcp_process_established(socket_core_t *, tcp_socket_data_t *,
     202    tcp_header_t *, packet_t *, int, size_t);
     203static int tcp_queue_received_packet(socket_core_t *, tcp_socket_data_t *,
     204    packet_t *, int, size_t);
     205static void tcp_queue_received_end_of_data(socket_core_t *socket);
     206
     207static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t);
     208static int tcp_process_client_messages(ipc_callid_t, ipc_call_t);
     209
     210static int tcp_listen_message(socket_cores_t *, int, int);
     211static int tcp_connect_message(socket_cores_t *, int, struct sockaddr *,
     212    socklen_t);
     213static int tcp_recvfrom_message(socket_cores_t *, int, int, size_t *);
     214static int tcp_send_message(socket_cores_t *, int, int, size_t *, int);
     215static int tcp_accept_message(socket_cores_t *, int, int, size_t *, size_t *);
     216static int tcp_close_message(socket_cores_t *, int);
     217
     218/** TCP global data. */
     219tcp_globals_t tcp_globals;
     220
     221int 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
    223229        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)
    247232                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
     239int tcp_process_packet(device_id_t device_id, packet_t *packet, services_t error)
     240{
    257241        size_t length;
    258242        size_t offset;
    259243        int result;
    260         tcp_header_ref header;
    261         socket_core_ref  socket;
    262         tcp_socket_data_ref socket_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;
    264248        size_t total_length;
    265249        uint32_t checksum;
     
    267251        icmp_type_t type;
    268252        icmp_code_t code;
    269         struct sockaddr * src;
    270         struct sockaddr * dest;
     253        struct sockaddr *src;
     254        struct sockaddr *dest;
    271255        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? */
    293278        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)
    296280                return tcp_release_and_return(packet, result);
    297         }
     281
    298282        offset = (size_t) result;
    299283
    300284        length = packet_get_data_length(packet);
    301 //      printf("packet len %d\n", length);
    302         if(length <= 0){
     285        if (length <= 0)
    303286                return tcp_release_and_return(packet, EINVAL);
    304         }
    305         if(length < TCP_HEADER_SIZE + offset){
     287
     288        if (length < TCP_HEADER_SIZE + offset)
    306289                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)
    317299                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
    321305        result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
    322         if(result <= 0){
     306        if (result <= 0)
    323307                return tcp_release_and_return(packet, result);
    324         }
     308
    325309        addrlen = (size_t) result;
    326310
    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
    344334        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;
    346336        assert(socket_data);
    347337
    348         // some data received, clear the timeout counter
     338        /* Some data received, clear the timeout counter */
    349339        socket_data->timeout_count = 0;
    350340
    351         // count the received packet fragments
     341        /* Count the received packet fragments */
    352342        next_packet = packet;
    353343        fragments = 0;
    354344        checksum = 0;
    355345        total_length = 0;
    356         do{
    357                 ++ fragments;
     346        do {
     347                fragments++;
    358348                length = packet_get_data_length(next_packet);
    359                 if(length <= 0){
     349                if (length <= 0)
    360350                        return tcp_release_and_return(packet, NO_DATA);
    361                 }
     351
    362352                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
    371363        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) {
    385379                        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) {
    391387                        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)));
    431397                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
     412has_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
    433449        return EOK;
    434450}
    435451
    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;
     452int 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;
    441458        uint32_t old_incoming;
    442459        size_t order;
     
    445462        size_t offset;
    446463        uint32_t new_sequence_number;
     464        bool forced_ack;
     465        int rc;
    447466
    448467        assert(socket);
     
    452471        assert(packet);
    453472
     473        forced_ack = false;
     474
    454475        new_sequence_number = ntohl(header->sequence_number);
    455476        old_incoming = socket_data->next_incoming;
    456477
    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
    471496                new_sequence_number += offset;
    472497                total_length -= offset;
    473498                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 */
    477503                        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));
    479506                        packet = next_packet;
    480507                        offset -= length;
    481508                        length = packet_get_data_length(packet);
    482509                }
    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
    487517                assert(new_sequence_number == socket_data->next_incoming);
    488518        }
    489519
    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 */
    495521/*
     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
    496528        // 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)) {
    498532                // 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;
    503540                }
    504541                next_packet = packet;
    505542                // trim the overflowing data
    506                 while(next_packet && (offset > 0)){
     543                while (next_packet && (offset > 0)) {
    507544                        length = packet_get_data_length(packet);
    508                         if(length <= offset){
     545                        if (length <= offset)
    509546                                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);
    512553                        }
    513554                        offset -= length;
     
    516557                // release the overflowing packets
    517558                next_packet = pq_next(next_packet);
    518                 if(next_packet){
     559                if (next_packet) {
    519560                        tmp_packet = next_packet;
    520561                        next_packet = pq_next(next_packet);
    521562                        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);
    525568        }
    526569*/
    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) {
    529572                printf("expected\n");
    530                 // process acknowledgement
     573                /* Process acknowledgement */
    531574                tcp_process_acknowledgement(socket, socket_data, header);
    532575
    533                 // remove the header
     576                /* Remove the header */
    534577                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 {
    542588                        total_length = 1;
    543589                }
     590
    544591                socket_data->next_incoming = old_incoming + total_length;
    545592                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 */
    549597                                next_packet = pq_detach(packet);
    550                                 if(packet == socket_data->incoming){
     598                                if (packet == socket_data->incoming)
    551599                                        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));
    554602                                packet = next_packet;
    555603                                continue;
    556604                        }
     605
    557606                        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 */
    560610                                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 */
    564615                                next_packet = pq_detach(packet);
    565                                 if(packet == socket_data->incoming){
     616                                if (packet == socket_data->incoming)
    566617                                        socket_data->incoming = next_packet;
    567                                 }
    568                                 // get data length
     618                                /* Get data length */
    569619                                length = packet_get_data_length(packet);
    570620                                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));
    574625                                        packet = next_packet;
    575626                                        continue;
    576627                                }
    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;
    582639                                        packet = next_packet;
    583640                                        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;
    590653                                        }
    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;
    595665                                                packet = next_packet;
    596666                                                continue;
    597667                                        }
    598668                                }
    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));
    601672                                packet = next_packet;
    602673                                continue;
    603                         }else{
     674                        } else {
    604675                                break;
    605676                        }
    606677                }
    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)) {
    608681                printf("in window\n");
    609                 // process acknowledgement
     682                /* Process acknowledgement */
    610683                tcp_process_acknowledgement(socket, socket_data, header);
    611684
    612                 // remove the header
     685                /* Remove the header */
    613686                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);
    617690
    618691                next_packet = pq_detach(packet);
    619692                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) {
    626703                                new_sequence_number += length;
    627704                                tmp_packet = pq_detach(next_packet);
    628705                                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));
    632717                                }
    633718                                next_packet = tmp_packet;
    634719                        }
    635720                }
    636         }else{
     721        } else {
    637722                printf("unexpected\n");
    638                 // release duplicite or restricted
     723                /* Release duplicite or restricted */
    639724                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;
    654748                }
    655749        }
    656750
    657751        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
    664765        fibril_rwlock_write_unlock(socket_data->local_lock);
    665         // send the packet
     766
     767        /* Send the packet */
    666768        tcp_send_packets(socket_data->device_id, packet);
     769
    667770        return EOK;
    668771}
    669772
    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;
     773int 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;
    674779
    675780        assert(socket);
     
    680785        assert(socket_data->window > total_length);
    681786
    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 */
    689798        socket_data->window -= total_length;
    690799
    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
    693807        return EOK;
    694808}
    695809
    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 */
     817static 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
     828int 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;
    700833
    701834        assert(socket);
     
    705838        assert(packet);
    706839
    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);
    740883        return tcp_release_and_return(packet, EINVAL);
    741884}
    742885
    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;
     886int 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;
    749894        int socket_id;
    750895        int listening_socket_id = listening_socket->socket_id;
    751896        int listening_port = listening_socket->port;
     897        int rc;
    752898
    753899        assert(listening_socket);
     
    757903        assert(packet);
    758904
    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
     1046int 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;
    8871052
    8881053        assert(socket);
     
    8921057        assert(packet);
    8931058
    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)
    9331060                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
     1113void tcp_process_acknowledgement(socket_core_t *socket,
     1114    tcp_socket_data_t *socket_data, tcp_header_t *header)
     1115{
    9391116        size_t number;
    9401117        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;
    9441121        uint32_t old;
    9451122
     
    9491126        assert(header);
    9501127
    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;
    9691155                        }
    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) {
    9761199                        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 */
     1209void 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 */
     1226int tl_message(ipc_callid_t callid, ipc_call_t *call,
     1227    ipc_call_t *answer, size_t *answer_count)
     1228{
    10161229        assert(call);
    10171230        assert(answer);
     
    10191232
    10201233        *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
    10321239        return ENOTSUP;
    10331240}
    10341241
    1035 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data){
     1242void tcp_refresh_socket_data(tcp_socket_data_t *socket_data)
     1243{
    10361244        assert(socket_data);
    10371245
     
    10481256}
    10491257
    1050 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data){
     1258void tcp_initialize_socket_data(tcp_socket_data_t *socket_data)
     1259{
    10511260        assert(socket_data);
    10521261
     
    10571266}
    10581267
    1059 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call){
     1268int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
     1269{
    10601270        int res;
    10611271        bool keep_on_going = true;
    10621272        socket_cores_t local_sockets;
    1063         int app_phone = IPC_GET_PHONE(&call);
    1064         struct sockaddr * addr;
     1273        int app_phone = IPC_GET_PHONE(call);
     1274        struct sockaddr *addr;
    10651275        int socket_id;
    10661276        size_t addrlen;
     
    10681278        fibril_rwlock_t lock;
    10691279        ipc_call_t answer;
    1070         int answer_count;
    1071         tcp_socket_data_ref socket_data;
    1072         socket_core_ref socket;
    1073         packet_dimension_ref packet_dimension;
     1280        size_t answer_count;
     1281        tcp_socket_data_t *socket_data;
     1282        socket_core_t *socket;
     1283        packet_dimension_t *packet_dimension;
    10741284
    10751285        /*
     
    10831293        fibril_rwlock_initialize(&lock);
    10841294
    1085         while(keep_on_going){
    1086 
    1087                 // answer the call
     1295        while (keep_on_going) {
     1296
     1297                /* Answer the call */
    10881298                answer_call(callid, res, &answer, answer_count);
    1089 
    1090                 // refresh data
     1299                /* Refresh data */
    10911300                refresh_answer(&answer, &answer_count);
    1092 
    1093                 // get the next call
     1301                /* Get the next call */
    10941302                callid = async_get_call(&call);
    10951303
    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;
    11011316                                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;
    11251365                                }
     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)
    11261388                                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) {
    11511398                                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) {
    11741429                                fibril_rwlock_write_unlock(&lock);
    11751430                                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)
    11811440                                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) {
    12141449                                fibril_rwlock_write_unlock(&lock);
    12151450                                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) {
    12261494                                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);
    12541509
    12551510        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);
    12581514
    12591515        return EOK;
    12601516}
    12611517
    1262 int tcp_timeout(void * data){
    1263         tcp_timeout_ref timeout = data;
     1518int tcp_timeout(void *data)
     1519{
     1520        tcp_timeout_t *timeout = data;
    12641521        int keep_write_lock = false;
    1265         socket_core_ref socket;
    1266         tcp_socket_data_ref socket_data;
     1522        socket_core_t *socket;
     1523        tcp_socket_data_t *socket_data;
    12671524
    12681525        assert(timeout);
    12691526
    1270         // sleep the given timeout
     1527        /* Sleep the given timeout */
    12711528        async_usleep(timeout->timeout);
    1272         // lock the globals
    1273         if(timeout->globals_read_only){
     1529        /* Lock the globals */
     1530        if (timeout->globals_read_only)
    12741531                fibril_rwlock_read_lock(&tcp_globals.lock);
    1275         }else{
     1532        else
    12761533                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
     1582out:
     1583        /* Unlock only if no socket */
     1584        if (timeout->globals_read_only)
    13171585                fibril_rwlock_read_unlock(&tcp_globals.lock);
    1318         }else if(! keep_write_lock){
    1319                 // release if not desired
     1586        else if (!keep_write_lock)
     1587                /* Release if not desired */
    13201588                fibril_rwlock_write_unlock(&tcp_globals.lock);
    1321         }
    1322         // release the timeout structure
     1589       
     1590        /* Release the timeout structure */
    13231591        free(timeout);
    13241592        return EOK;
    13251593}
    13261594
    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;
     1595int 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;
    13321601
    13331602        assert(timeout);
    13341603
    1335         // sleep the given timeout
     1604        /* Sleep the given timeout */
    13361605        async_usleep(timeout->timeout);
    1337         // lock the globals
     1606
     1607        /* Lock the globals */
    13381608        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;
    13431616                assert(socket_data);
    1344                 if(socket_data->local_sockets == timeout->local_sockets){
     1617                if (socket_data->local_sockets == timeout->local_sockets) {
    13451618                        local_lock = socket_data->local_lock;
    13461619                        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);
    13481623                        fibril_rwlock_write_unlock(local_lock);
    13491624                }
    13501625        }
    1351         // unlock the globals
     1626
     1627        /* Unlock the globals */
    13521628        fibril_rwlock_write_unlock(&tcp_globals.lock);
    1353         // release the timeout structure
     1629
     1630        /* Release the timeout structure */
    13541631        free(timeout);
     1632
    13551633        return EOK;
    13561634}
    13571635
    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;
     1636void 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;
    13611641        size_t data_length;
    13621642
     
    13651645        assert(socket->specific_data == socket_data);
    13661646
    1367         // sent packet?
     1647        /* Sent packet? */
    13681648        packet = pq_find(socket_data->outgoing, sequence_number);
    13691649        printf("retransmit %d\n", packet_get_id(packet));
    1370         if(packet){
     1650        if (packet) {
    13711651                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);
    13731654                fibril_rwlock_write_unlock(socket_data->local_lock);
    1374 //              printf("r send %d\n", packet_get_id(packet));
    1375                 if(copy){
     1655//              printf("r send %d\n", packet_get_id(packet));
     1656                if (copy)
    13761657                        tcp_send_packets(socket_data->device_id, copy);
    1377                 }
    1378         }else{
     1658        } else {
    13791659                fibril_rwlock_write_unlock(socket_data->local_lock);
    13801660        }
    13811661}
    13821662
    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;
     1663int 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;
    13861668
    13871669        assert(local_sockets);
    13881670
    1389         if(backlog < 0){
     1671        if (backlog < 0)
    13901672                return EINVAL;
    1391         }
    1392         // find the socket
     1673
     1674        /* Find the socket */
    13931675        socket = socket_cores_find(local_sockets, socket_id);
    1394         if(! socket){
     1676        if (!socket)
    13951677                return ENOTSOCK;
    1396         }
    1397         // get the socket specific data
    1398         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;
    13991681        assert(socket_data);
    1400         // set the backlog
     1682
     1683        /* Set the backlog */
    14011684        socket_data->backlog = backlog;
     1685
    14021686        return EOK;
    14031687}
    14041688
    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;
     1689int 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;
    14091694
    14101695        assert(local_sockets);
     
    14121697        assert(addrlen > 0);
    14131698
    1414         // find the socket
     1699        /* Find the socket */
    14151700        socket = socket_cores_find(local_sockets, socket_id);
    1416         if(! socket){
     1701        if (!socket)
    14171702                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) {
    14201706                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);
    14241711                        socket->port = 0;
    14251712                }
    14261713        }
    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
     1717int 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;
    14351723
    14361724        assert(socket);
     
    14381726        assert(addrlen > 0);
    14391727
    1440         // get the socket specific data
    1441         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;
    14421730        assert(socket_data);
    14431731        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)))
    14461735                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 */
    14541750                tcp_globals.last_used_port = socket->port;
    14551751        }
    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 */
    14621765        fibril_rwlock_write_unlock(&tcp_globals.lock);
    14631766
    14641767        socket_data->addr = addr;
    14651768        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)) {
    14691776                socket_data->addr = NULL;
    14701777                socket_data->addrlen = 0;
    14711778                fibril_rwlock_write_lock(&tcp_globals.lock);
    1472         }else{
     1779        } else {
    14731780                packet = tcp_get_packets_to_send(socket, socket_data);
    1474                 if(packet){
     1781                if (packet) {
    14751782                        fibril_mutex_lock(&socket_data->operation.mutex);
    14761783                        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 */
    14781788                        printf("connecting %d\n", packet_get_id(packet));
    14791789                        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) {
    14841796                                socket_data->addr = NULL;
    14851797                                socket_data->addrlen = 0;
    14861798                        }
    1487                 }else{
     1799                } else {
    14881800                        socket_data->addr = NULL;
    14891801                        socket_data->addrlen = 0;
    1490                         ERROR_CODE = EINTR;
     1802                        rc = EINTR;
    14911803                }
    14921804        }
    14931805
    14941806        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
     1810int 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;
    15041815
    15051816        assert(socket);
     
    15071818        assert(socket->specific_data == socket_data);
    15081819
    1509         // get tcp header
    1510         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)
    15121823                return NO_DATA;
    1513         }
     1824       
    15141825        header->destination_port = htons(socket_data->dest_port);
    15151826        header->source_port = htons(socket->port);
    15161827        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)
    15181832                return tcp_release_and_return(packet, EINVAL);
    1519         }
    1520         // remember the outgoing FIN
    1521         if(header->finalize){
     1833
     1834        /* Remember the outgoing FIN */
     1835        if (header->finalize)
    15221836                socket_data->fin_outgoing = socket_data->next_outgoing;
    1523         }
     1837       
    15241838        return EOK;
    15251839}
    15261840
    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;
     1841int 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;
    15291845
    15301846        assert(socket);
     
    15321848        assert(socket->specific_data == socket_data);
    15331849
    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
    15391859        socket_data->next_outgoing += data_length;
    15401860        return EOK;
    15411861}
    15421862
    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;
     1863packet_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;
    15501870        size_t data_length;
     1871        int rc;
    15511872
    15521873        assert(socket);
     
    15551876
    15561877        packet = pq_find(socket_data->outgoing, socket_data->last_outgoing + 1);
    1557         while(packet){
     1878        while (packet) {
    15581879                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));
    15641903                                return sending;
    15651904                        }
    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
    15871920        return sending;
    15881921}
    15891922
    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_ref header;
     1923packet_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;
    15941927        uint32_t checksum;
     1928        int rc;
    15951929
    15961930        assert(socket);
     
    15981932        assert(socket->specific_data == socket_data);
    15991933
    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) {
    16021938                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    16031939                return NULL;
    16041940        }
    16051941
    1606         // get the header
    1607         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) {
    16091945                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    16101946                return NULL;
     
    16121948        assert(ntohl(header->sequence_number) == sequence_number);
    16131949
    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);
    16171954                header->acknowledge = 1;
    16181955        }
    16191956        header->window = htons(socket_data->window);
    16201957
    1621         // checksum
     1958        /* Checksum */
    16221959        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));
    16251965        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 timeout
    1629                 || 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) {
    16301970                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    16311971                return NULL;
    16321972        }
     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
    16331981        return packet;
    16341982}
    16351983
    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;
     1984packet_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;
    16381988
    16391989        assert(socket);
     
    16411991        assert(socket->specific_data == socket_data);
    16421992
    1643         // make a copy of the packet
     1993        /* Make a copy of the packet */
    16441994        copy = packet_get_copy(tcp_globals.net_phone, packet);
    1645         if(! copy){
     1995        if (!copy)
    16461996                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
     2002void tcp_send_packets(device_id_t device_id, packet_t *packet)
     2003{
     2004        packet_t *next;
     2005
     2006        while (packet) {
    16562007                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);
    16582010                packet = next;
    16592011        }
    16602012}
    16612013
    1662 void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize){
     2014void 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{
    16632018        assert(socket);
    16642019        assert(socket_data);
     
    16742029}
    16752030
    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;
     2031int 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;
    16782037        fid_t fibril;
    16792038
     
    16822041        assert(socket->specific_data == socket_data);
    16832042
    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)
    16872047                return ENOMEM;
    1688         }
     2048
    16892049        bzero(operation_timeout, sizeof(*operation_timeout));
    16902050        operation_timeout->globals_read_only = globals_read_only;
     
    16962056        operation_timeout->state = state;
    16972057
    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);
    17002061        operation_timeout->key_length = socket->key_length;
    17012062        memcpy(operation_timeout->key, socket->key, socket->key_length);
    17022063        operation_timeout->key[operation_timeout->key_length] = '\0';
    17032064
    1704         // prepare the timeouting thread
     2065        /* Prepare the timeouting thread */
    17052066        fibril = fibril_create(timeout_function, operation_timeout);
    1706         if(! fibril){
     2067        if (!fibril) {
    17072068                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 */
    17122074        fibril_add_ready(fibril);
    17132075        //socket_data->state = state;
     
    17152077}
    17162078
    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_ref socket;
    1721         tcp_socket_data_ref socket_data;
     2079int 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;
    17222084        int packet_id;
    1723         packet_t packet;
     2085        packet_t *packet;
    17242086        size_t length;
     2087        int rc;
    17252088
    17262089        assert(local_sockets);
    17272090
    1728         // find the socket
     2091        /* Find the socket */
    17292092        socket = socket_cores_find(local_sockets, socket_id);
    1730         if(! socket){
     2093        if (!socket)
    17312094                return ENOTSOCK;
    1732         }
    1733         // get the socket specific data
    1734         if(! socket->specific_data){
     2095
     2096        /* Get the socket specific data */
     2097        if (!socket->specific_data)
    17352098                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))
    17412105                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;
    17472112                *addrlen = socket_data->addrlen;
    17482113        }
    17492114
    1750         // get the next received packet
     2115        /* Get the next received packet */
    17512116        packet_id = dyn_fifo_value(&socket->received);
    1752         if(packet_id < 0){
     2117        if (packet_id < 0)
    17532118                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 */
    17612130        dyn_fifo_pop(&socket->received);
    17622131        pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    1763         // return the total length
     2132
     2133        /* Return the total length */
    17642134        return (int) length;
    17652135}
    17662136
    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_ref socket;
    1771         tcp_socket_data_ref socket_data;
    1772         packet_dimension_ref packet_dimension;
    1773         packet_t packet;
     2137int 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;
    17742144        size_t total_length;
    1775         tcp_header_ref header;
     2145        tcp_header_t *header;
    17762146        int index;
    17772147        int result;
     2148        int rc;
    17782149
    17792150        assert(local_sockets);
    17802151        assert(data_fragment_size);
    17812152
    1782         // find the socket
     2153        /* Find the socket */
    17832154        socket = socket_cores_find(local_sockets, socket_id);
    1784         if(! socket){
     2155        if (!socket)
    17852156                return ENOTSOCK;
    1786         }
    1787         // get the socket specific data
    1788         if(! socket->specific_data){
     2157
     2158        /* Get the socket specific data */
     2159        if (!socket->specific_data)
    17892160                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))
    17952167                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)
    18062184                        return result;
    1807                 }
     2185
    18082186                total_length = (size_t) result;
    1809                 // prefix the tcp header
     2187
     2188                /* Prefix the TCP header */
    18102189                header = PACKET_PREFIX(packet, tcp_header_t);
    1811                 if(! header){
     2190                if (!header)
    18122191                        return tcp_release_and_return(packet, ENOMEM);
    1813                 }
     2192
    18142193                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 */
    18192200        packet = tcp_get_packets_to_send(socket, socket_data);
    18202201        fibril_rwlock_write_unlock(socket_data->local_lock);
    18212202        fibril_rwlock_read_unlock(&tcp_globals.lock);
    1822         if(packet){
    1823                 // send the packet
     2203
     2204        if (packet) {
     2205                /* Send the packet */
    18242206                tcp_send_packets(socket_data->device_id, packet);
    18252207        }
     
    18282210}
    18292211
    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
     2212int
     2213tcp_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 */
    18382221        socket = socket_cores_find(local_sockets, socket_id);
    1839         if(! socket){
     2222        if (!socket)
    18402223                return ENOTSOCK;
    1841         }
    1842         // get the socket specific data
    1843         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;
    18442227        assert(socket_data);
    18452228
    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 */
    18732269        packet = tcp_get_packets_to_send(socket, socket_data);
    18742270        fibril_rwlock_write_unlock(socket_data->local_lock);
    18752271        fibril_rwlock_write_unlock(&tcp_globals.lock);
    1876         if(packet){
    1877                 // send the packet
     2272
     2273        if (packet) {
     2274                /* Send the packet */
    18782275                tcp_send_packets(socket_data->device_id, packet);
    18792276        }
     2277
    18802278        return EOK;
    18812279}
    18822280
    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;
     2281int 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;
    18882287
    18892288        assert(packet);
    18902289
    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)
    18962302                return ENOMEM;
    1897         }
    1898         // allocate space in the packet
     2303
     2304        /* Allocate space in the packet */
    18992305        header = PACKET_SUFFIX(*packet, tcp_header_t);
    1900         if(! header){
     2306        if (!header)
    19012307                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
    19052312        return EOK;
    19062313}
    19072314
    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;
     2315int 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;
    19152323
    19162324        assert(local_sockets);
     
    19182326        assert(addrlen);
    19192327
    1920         // find the socket
     2328        /* Find the socket */
    19212329        socket = socket_cores_find(local_sockets, socket_id);
    1922         if(! socket){
     2330        if (!socket)
    19232331                return ENOTSOCK;
    1924         }
    1925         // get the socket specific data
    1926         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;
    19272335        assert(socket_data);
    19282336
    1929         // check state
    1930         if(socket_data->state != TCP_SOCKET_LISTEN){
     2337        /* Check state */
     2338        if (socket_data->state != TCP_SOCKET_LISTEN)
    19312339                return EINVAL;
    1932         }
    1933 
    1934         do{
     2340
     2341        do {
    19352342                socket_id = dyn_fifo_value(&socket->accepted);
    1936                 if(socket_id < 0){
     2343                if (socket_id < 0)
    19372344                        return ENOTSOCK;
    1938                 }
    19392345                socket_id *= -1;
    19402346
    19412347                accepted = socket_cores_find(local_sockets, socket_id);
    1942                 if(! accepted){
     2348                if (!accepted)
    19432349                        return ENOTSOCK;
    1944                 }
    1945                 // get the socket specific data
    1946                 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;
    19472353                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;
    19522365                        *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;
    19562378                                accepted->socket_id = new_socket_id;
    19572379                        }
    19582380                }
    19592381                dyn_fifo_pop(&socket->accepted);
    1960         }while(socket_data->state != TCP_SOCKET_ESTABLISHED);
     2382        } while (socket_data->state != TCP_SOCKET_ESTABLISHED);
     2383
    19612384        printf("ret accept %d\n", accepted->socket_id);
    19622385        return accepted->socket_id;
    19632386}
    19642387
    1965 void tcp_free_socket_data(socket_core_ref socket){
    1966         tcp_socket_data_ref socket_data;
     2388void tcp_free_socket_data(socket_core_t *socket)
     2389{
     2390        tcp_socket_data_t *socket_data;
    19672391
    19682392        assert(socket);
     
    19702394        printf("destroy_socket %d\n", socket->socket_id);
    19712395
    1972         // get the socket specific data
    1973         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;
    19742398        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) {
    19782403                        printf("d pseudo\n");
    19792404                        free(socket_data->pseudo_header);
     
    19822407                socket_data->pseudo_header = NULL;
    19832408        }
     2409
    19842410        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) {
    19882415                        printf("d addr\n");
    19892416                        free(socket_data->addr);
     
    19952422}
    19962423
    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 */
     2430int tcp_release_and_return(packet_t *packet, int result)
     2431{
    19982432        pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    19992433        return result;
    20002434}
    20012435
    2002 /** Default thread for new connections.
     2436/** Process IPC messages from the IP module
    20032437 *
    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.
    20062440 *
    20072441 */
    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);
     2442static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall)
     2443{
     2444        packet_t *packet;
     2445        int rc;
    20152446       
    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                }
    20192461               
    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.
    20412467 *
    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.
    20442469 *
    2045  *  @returns EOK 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.
    20472472 *
    20482473 */
     2474int 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
     2501out:
     2502        fibril_rwlock_write_unlock(&tcp_globals.lock);
     2503        return rc;
     2504}
     2505
    20492506int main(int argc, char *argv[])
    20502507{
    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);
    20582509}
    20592510
Note: See TracChangeset for help on using the changeset viewer.