Ignore:
File:
1 edited

Legend:

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

    r89e57cee r472020fc  
    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 */
    37 
    38 #include "tcp.h"
    39 #include "tcp_header.h"
    40 #include "tcp_module.h"
    4137
    4238#include <assert.h>
     
    7672#include <tl_interface.h>
    7773
     74#include "tcp.h"
     75#include "tcp_header.h"
     76#include "tcp_module.h"
     77
    7878/** TCP module name. */
    7979#define NAME    "TCP protocol"
     
    110110
    111111/** Returns a value indicating whether the value is in the interval respecting
    112  * the possible overflow.
     112 *  the possible overflow.
    113113 *
    114  * The high end and/or the value may overflow, be lower than the low value.
    115  *
    116  * @param[in] lower     The last value before the interval.
    117  * @param[in] value     The value to be checked.
    118  * @param[in] higher_equal The last value in the interval.
     114 *  The high end and/or the value may overflow, be lower than the low value.
     115 *  @param[in] lower The last value before the interval.
     116 *  @param[in] value The value to be checked.
     117 *  @param[in] higher_equal The last value in the interval.
    119118 */
    120119#define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \
     
    166165};
    167166
    168 static int tcp_release_and_return(packet_t, int);
    169 static void tcp_prepare_operation_header(socket_core_ref, tcp_socket_data_ref,
    170     tcp_header_ref, int synchronize, int);
    171 static int tcp_prepare_timeout(int (*)(void *), socket_core_ref,
    172     tcp_socket_data_ref, size_t, tcp_socket_state_t, suseconds_t, int);
    173 static void tcp_free_socket_data(socket_core_ref);
    174 
    175 static int tcp_timeout(void *);
    176 
    177 static int tcp_release_after_timeout(void *);
    178 
    179 static int tcp_process_packet(device_id_t, packet_t, services_t);
    180 static int tcp_connect_core(socket_core_ref, socket_cores_ref,
    181     struct sockaddr *, socklen_t);
    182 static int tcp_queue_prepare_packet(socket_core_ref, tcp_socket_data_ref,
    183     packet_t, size_t);
    184 static int tcp_queue_packet(socket_core_ref, tcp_socket_data_ref, packet_t,
    185     size_t);
    186 static packet_t tcp_get_packets_to_send(socket_core_ref, tcp_socket_data_ref);
    187 static void tcp_send_packets(device_id_t, packet_t);
    188 
    189 static void tcp_process_acknowledgement(socket_core_ref, tcp_socket_data_ref,
    190     tcp_header_ref);
    191 static packet_t tcp_send_prepare_packet(socket_core_ref, tcp_socket_data_ref,
    192     packet_t, size_t, size_t);
    193 static packet_t tcp_prepare_copy(socket_core_ref, tcp_socket_data_ref, packet_t,
    194     size_t, size_t);
    195 /* static */ void tcp_retransmit_packet(socket_core_ref, tcp_socket_data_ref,
    196     size_t);
    197 static int tcp_create_notification_packet(packet_t *, socket_core_ref,
    198     tcp_socket_data_ref, int, int);
    199 static void tcp_refresh_socket_data(tcp_socket_data_ref);
    200 
    201 static void tcp_initialize_socket_data(tcp_socket_data_ref);
    202 
    203 static int tcp_process_listen(socket_core_ref, tcp_socket_data_ref,
    204     tcp_header_ref, packet_t, struct sockaddr *, struct sockaddr *, size_t);
    205 static int tcp_process_syn_sent(socket_core_ref, tcp_socket_data_ref,
    206     tcp_header_ref, packet_t);
    207 static int tcp_process_syn_received(socket_core_ref, tcp_socket_data_ref,
    208     tcp_header_ref, packet_t);
    209 static int tcp_process_established(socket_core_ref, tcp_socket_data_ref,
    210     tcp_header_ref, packet_t, int, size_t);
    211 static int tcp_queue_received_packet(socket_core_ref, tcp_socket_data_ref,
    212     packet_t, int, size_t);
    213 
    214 static int tcp_received_msg(device_id_t, packet_t, services_t, services_t);
    215 static int tcp_process_client_messages(ipc_callid_t, ipc_call_t);
    216 
    217 static int tcp_listen_message(socket_cores_ref, int, int);
    218 static int tcp_connect_message(socket_cores_ref, int, struct sockaddr *,
    219     socklen_t);
    220 static int tcp_recvfrom_message(socket_cores_ref, int, int, size_t *);
    221 static int tcp_send_message(socket_cores_ref, int, int, size_t *, int);
    222 static int tcp_accept_message(socket_cores_ref, int, int, size_t *, size_t *);
    223 static int tcp_close_message(socket_cores_ref, int);
     167/** Releases the packet and returns the result.
     168 *  @param[in] packet The packet queue to be released.
     169 *  @param[in] result The result to be returned.
     170 *  @return The result parameter.
     171 */
     172int tcp_release_and_return(packet_t packet, int result);
     173
     174void tcp_prepare_operation_header(socket_core_ref socket,
     175    tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize,
     176    int finalize);
     177int tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t),
     178    socket_core_ref socket, tcp_socket_data_ref socket_data,
     179    size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout,
     180    int globals_read_only);
     181void tcp_free_socket_data(socket_core_ref socket);
     182
     183int tcp_timeout(void *data);
     184
     185int tcp_release_after_timeout(void *data);
     186
     187int tcp_process_packet(device_id_t device_id, packet_t packet,
     188    services_t error);
     189int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets,
     190    struct sockaddr *addr, socklen_t addrlen);
     191int tcp_queue_prepare_packet(socket_core_ref socket,
     192    tcp_socket_data_ref socket_data, packet_t packet, size_t data_length);
     193int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data,
     194    packet_t packet, size_t data_length);
     195packet_t tcp_get_packets_to_send(socket_core_ref socket,
     196    tcp_socket_data_ref socket_data);
     197void tcp_send_packets(device_id_t device_id, packet_t packet);
     198
     199void tcp_process_acknowledgement(socket_core_ref socket,
     200    tcp_socket_data_ref socket_data, tcp_header_ref header);
     201packet_t tcp_send_prepare_packet(socket_core_ref socket,
     202    tcp_socket_data_ref socket_data, packet_t packet, size_t data_length,
     203    size_t sequence_number);
     204packet_t tcp_prepare_copy(socket_core_ref socket,
     205    tcp_socket_data_ref socket_data, packet_t packet, size_t data_length,
     206    size_t sequence_number);
     207void tcp_retransmit_packet(socket_core_ref socket,
     208    tcp_socket_data_ref socket_data, size_t sequence_number);
     209int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket,
     210    tcp_socket_data_ref socket_data, int synchronize, int finalize);
     211void tcp_refresh_socket_data(tcp_socket_data_ref socket_data);
     212
     213void tcp_initialize_socket_data(tcp_socket_data_ref socket_data);
     214
     215int tcp_process_listen(socket_core_ref listening_socket,
     216    tcp_socket_data_ref listening_socket_data, tcp_header_ref header,
     217    packet_t packet, struct sockaddr *src, struct sockaddr *dest,
     218    size_t addrlen);
     219int tcp_process_syn_sent(socket_core_ref socket,
     220    tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
     221int tcp_process_syn_received(socket_core_ref socket,
     222    tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
     223int tcp_process_established(socket_core_ref socket,
     224    tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet,
     225    int fragments, size_t total_length);
     226int tcp_queue_received_packet(socket_core_ref socket,
     227    tcp_socket_data_ref socket_data, packet_t packet, int fragments,
     228    size_t total_length);
     229
     230int tcp_received_msg(device_id_t device_id, packet_t packet,
     231    services_t receiver, services_t error);
     232int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
     233
     234int tcp_listen_message(socket_cores_ref local_sockets, int socket_id,
     235    int backlog);
     236int tcp_connect_message(socket_cores_ref local_sockets, int socket_id,
     237    struct sockaddr *addr, socklen_t addrlen);
     238int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id,
     239    int flags, size_t * addrlen);
     240int tcp_send_message(socket_cores_ref local_sockets, int socket_id,
     241    int fragments, size_t * data_fragment_size, int flags);
     242int tcp_accept_message(socket_cores_ref local_sockets, int socket_id,
     243    int new_socket_id, size_t * data_fragment_size, size_t * addrlen);
     244int tcp_close_message(socket_cores_ref local_sockets, int socket_id);
    224245
    225246/** TCP global data. */
    226247tcp_globals_t tcp_globals;
    227248
    228 /** Initializes the TCP module.
    229  *
    230  * @param[in] client_connection The client connection processing function. The
    231  *                      module skeleton propagates its own one.
    232  * @returns             EOK on success.
    233  * @returns             ENOMEM if there is not enough memory left.
    234  */
    235249int tcp_initialize(async_client_conn_t client_connection)
    236250{
     
    300314        size_t addrlen;
    301315
    302         switch (error) {
    303         case SERVICE_NONE:
    304                 break;
    305         case SERVICE_ICMP:
    306                 // process error
    307                 result = icmp_client_process_packet(packet, &type, &code, NULL,
    308                     NULL);
    309                 if (result < 0)
    310                         return tcp_release_and_return(packet, result);
    311 
    312                 length = (size_t) result;
    313                 if (ERROR_OCCURRED(packet_trim(packet, length, 0)))
    314                         return tcp_release_and_return(packet, ERROR_CODE);
    315                 break;
    316         default:
    317                 return tcp_release_and_return(packet, ENOTSUP);
     316        if (error) {
     317                switch (error) {
     318                case SERVICE_ICMP:
     319                        // process error
     320                        result = icmp_client_process_packet(packet, &type,
     321                            &code, NULL, NULL);
     322                        if (result < 0)
     323                                return tcp_release_and_return(packet, result);
     324
     325                        length = (size_t) result;
     326                        if (ERROR_OCCURRED(packet_trim(packet, length, 0))) {
     327                                return tcp_release_and_return(packet,
     328                                    ERROR_CODE);
     329                        }
     330                        break;
     331
     332                default:
     333                        return tcp_release_and_return(packet, ENOTSUP);
     334                }
    318335        }
    319336
     
    362379                    ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING,
    363380                    0);
    364         }
    365         if (!socket) {
    366                 if (tl_prepare_icmp_packet(tcp_globals.net_phone,
    367                     tcp_globals.icmp_phone, packet, error) == EOK) {
    368                         icmp_destination_unreachable_msg(tcp_globals.icmp_phone,
    369                             ICMP_PORT_UNREACH, 0, packet);
    370                 }
    371                 return EADDRNOTAVAIL;
    372         }
    373 
     381                if (!socket) {
     382                        if (tl_prepare_icmp_packet(tcp_globals.net_phone,
     383                            tcp_globals.icmp_phone, packet, error) == EOK) {
     384                                icmp_destination_unreachable_msg(
     385                                    tcp_globals.icmp_phone, ICMP_PORT_UNREACH,
     386                                    0, packet);
     387                        }
     388                        return EADDRNOTAVAIL;
     389                }
     390        }
    374391        printf("socket id %d\n", socket->socket_id);
    375392        socket_data = (tcp_socket_data_ref) socket->specific_data;
     
    385402        total_length = 0;
    386403        do {
    387                 fragments++;
     404                ++fragments;
    388405                length = packet_get_data_length(next_packet);
    389406                if (length <= 0)
     
    404421
    405422        if (error)
    406                 goto has_error_service;
     423                goto error;
    407424       
    408425        if (socket_data->state == TCP_SOCKET_LISTEN) {
     426
    409427                if (socket_data->pseudo_header) {
    410428                        free(socket_data->pseudo_header);
     
    446464        }
    447465
    448 has_error_service:
     466error:
    449467        fibril_rwlock_read_unlock(&tcp_globals.lock);
    450468
     
    489507int
    490508tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data,
    491     tcp_header_ref header, packet_t packet, int fragments, size_t total_length)
     509    tcp_header_ref header, packet_t packet, int fragments,
     510    size_t total_length)
    492511{
    493512        ERROR_DECLARE;
     
    665684                                        continue;
    666685                                        // at least partly following data?
    667                                 }
    668                                 if (IS_IN_INTERVAL_OVERFLOW(sequence_number,
    669                                     socket_data->next_incoming, new_sequence_number)) {
     686                                } else if (IS_IN_INTERVAL_OVERFLOW(
     687                                    sequence_number, socket_data->next_incoming,
     688                                    new_sequence_number)) {
    670689                                        if (socket_data->next_incoming <
    671690                                            new_sequence_number) {
     
    942961        listening_socket = socket_port_find(&tcp_globals.sockets,
    943962            listening_port, SOCKET_MAP_KEY_LISTENING, 0);
    944         if (!listening_socket ||
     963        if ((!listening_socket) ||
    945964            (listening_socket->socket_id != listening_socket_id)) {
    946965                fibril_rwlock_write_unlock(&tcp_globals.lock);
     
    11721191        if (number == socket_data->expected) {
    11731192                // increase the counter
    1174                 socket_data->expected_count++;
     1193                ++socket_data->expected_count;
    11751194                if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) {
    11761195                        socket_data->expected_count = 1;
     
    11811200}
    11821201
    1183 /** Processes the TCP message.
    1184  *
    1185  * @param[in] callid    The message identifier.
    1186  * @param[in] call      The message parameters.
    1187  * @param[out] answer   The message answer parameters.
    1188  * @param[out] answer_count The last parameter for the actual answer in the
    1189  *                      answer parameter.
    1190  * @returns             EOK on success.
    1191  * @returns             ENOTSUP if the message is not known.
    1192  *
    1193  * @see tcp_interface.h
    1194  * @see IS_NET_TCP_MESSAGE()
    1195  */
    1196 int
    1197 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    1198     ipc_call_t *answer, int *answer_count)
     1202int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call,
     1203    ipc_call_t * answer, int *answer_count)
    11991204{
    12001205        ERROR_DECLARE;
     
    15161521        socket = socket_port_find(&tcp_globals.sockets, timeout->port,
    15171522            timeout->key, timeout->key_length);
    1518         if (!socket || (socket->socket_id != timeout->socket_id))
     1523        if (!(socket && (socket->socket_id == timeout->socket_id)))
    15191524                goto out;
    15201525       
     
    15271532        if (timeout->sequence_number) {
    15281533                // increase the timeout counter;
    1529                 socket_data->timeout_count++;
     1534                ++socket_data->timeout_count;
    15301535                if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) {
    15311536                        // TODO release as connection lost
     
    17391744            ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data,
    17401745            0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))) {
     1746
    17411747                socket_data->addr = NULL;
    17421748                socket_data->addrlen = 0;
    17431749                fibril_rwlock_write_lock(&tcp_globals.lock);
     1750
    17441751        } else {
     1752
    17451753                packet = tcp_get_packets_to_send(socket, socket_data);
    17461754                if (packet) {
     
    18681876                packet = pq_next(packet);
    18691877                // overflow occurred ?
    1870                 if (!packet &&
     1878                if ((!packet) &&
    18711879                    (socket_data->last_outgoing > socket_data->next_outgoing)) {
    18721880                        printf("gpts overflow\n");
     
    20362044int
    20372045tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
    2038     size_t *addrlen)
     2046    size_t * addrlen)
    20392047{
    20402048        ERROR_DECLARE;
     
    20912099int
    20922100tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments,
    2093     size_t *data_fragment_size, int flags)
     2101    size_t * data_fragment_size, int flags)
    20942102{
    20952103        ERROR_DECLARE;
     
    21302138            packet_dimension->content : socket_data->data_fragment_size);
    21312139
    2132         for (index = 0; index < fragments; index++) {
     2140        for (index = 0; index < fragments; ++index) {
    21332141                // read the data fragment
    21342142                result = tl_socket_read_packet_data(tcp_globals.net_phone,
     
    22272235
    22282236int
    2229 tcp_create_notification_packet(packet_t *packet, socket_core_ref socket,
     2237tcp_create_notification_packet(packet_t * packet, socket_core_ref socket,
    22302238    tcp_socket_data_ref socket_data, int synchronize, int finalize)
    22312239{
     
    22632271int
    22642272tcp_accept_message(socket_cores_ref local_sockets, int socket_id,
    2265     int new_socket_id, size_t *data_fragment_size, size_t *addrlen)
     2273    int new_socket_id, size_t * data_fragment_size, size_t * addrlen)
    22662274{
    22672275        ERROR_DECLARE;
     
    23652373}
    23662374
    2367 /** Releases the packet and returns the result.
    2368  *
    2369  * @param[in] packet    The packet queue to be released.
    2370  * @param[in] result    The result to be returned.
    2371  * @return              The result parameter.
    2372  */
    23732375int tcp_release_and_return(packet_t packet, int result)
    23742376{
     
    23792381/** Default thread for new connections.
    23802382 *
    2381  * @param[in] iid       The initial message identifier.
    2382  * @param[in] icall     The initial message call structure.
     2383 *  @param[in] iid The initial message identifier.
     2384 *  @param[in] icall The initial message call structure.
    23832385 *
    23842386 */
     
    23952397                int answer_count;
    23962398
    2397                 /* Clear the answer structure */
     2399                /*
     2400                   Clear the answer structure
     2401                 */
    23982402                refresh_answer(&answer, &answer_count);
    23992403
    2400                 /* Fetch the next message */
     2404                /*
     2405                   Fetch the next message
     2406                 */
    24012407                ipc_call_t call;
    24022408                ipc_callid_t callid = async_get_call(&call);
    24032409
    2404                 /* Process the message */
     2410                /*
     2411                   Process the message
     2412                 */
    24052413                int res = tl_module_message_standalone(callid, &call, &answer,
    24062414                    &answer_count);
    24072415
    24082416                /*
    2409                  * End if told to either by the message or the processing
    2410                  * result.
     2417                   End if said to either by the message or the processing result
    24112418                 */
    24122419                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     
    24232430/** Starts the module.
    24242431 *
    2425  * @returns             EOK on success.
    2426  * @returns             Other error codes as defined for each specific module
    2427  *                      start function.
     2432 *  @param argc The count of the command line arguments. Ignored parameter.
     2433 *  @param argv The command line parameters. Ignored parameter.
     2434 *
     2435 *  @returns EOK on success.
     2436 *  @returns Other error codes as defined for each specific module start function.
     2437 *
    24282438 */
    24292439int
Note: See TracChangeset for help on using the changeset viewer.