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


Ignore:
Timestamp:
2011-03-30T13:10:24Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4ae90f9
Parents:
6e50466 (diff), d6b81941 (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

    r6e50466 rad7a6c9  
    3636 */
    3737
    38 #include "tcp.h"
    39 #include "tcp_header.h"
    40 #include "tcp_module.h"
    41 
    4238#include <assert.h>
    4339#include <async.h>
     
    4844#include <errno.h>
    4945
    50 #include <ipc/ipc.h>
    5146#include <ipc/services.h>
    5247#include <ipc/net.h>
     
    6863#include <ip_interface.h>
    6964#include <icmp_client.h>
    70 #include <icmp_interface.h>
     65#include <icmp_remote.h>
    7166#include <net_interface.h>
    7267#include <socket_core.h>
    7368#include <tl_common.h>
    74 #include <tl_local.h>
    75 #include <tl_interface.h>
     69#include <tl_remote.h>
     70#include <tl_skel.h>
     71
     72#include "tcp.h"
     73#include "tcp_header.h"
    7674
    7775/** TCP module name. */
    78 #define NAME    "TCP protocol"
     76#define NAME  "tcp"
    7977
    8078/** The TCP window default value. */
     
    154152
    155153        /** Port map key. */
    156         char *key;
     154        uint8_t *key;
    157155
    158156        /** Port map key length. */
     
    205203static int tcp_queue_received_packet(socket_core_t *, tcp_socket_data_t *,
    206204    packet_t *, int, size_t);
     205static void tcp_queue_received_end_of_data(socket_core_t *socket);
    207206
    208207static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t);
     
    219218/** TCP global data. */
    220219tcp_globals_t tcp_globals;
    221 
    222 /** Initializes the TCP module.
    223  *
    224  * @param[in] client_connection The client connection processing function. The
    225  *                      module skeleton propagates its own one.
    226  * @return              EOK on success.
    227  * @return              ENOMEM if there is not enough memory left.
    228  */
    229 int tcp_initialize(async_client_conn_t client_connection)
    230 {
    231         int rc;
    232 
    233         assert(client_connection);
    234 
    235         fibril_rwlock_initialize(&tcp_globals.lock);
    236         fibril_rwlock_write_lock(&tcp_globals.lock);
    237 
    238         tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
    239             ICMP_CONNECT_TIMEOUT);
    240         tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
    241             SERVICE_TCP, client_connection);
    242         if (tcp_globals.ip_phone < 0) {
    243                 fibril_rwlock_write_unlock(&tcp_globals.lock);
    244                 return tcp_globals.ip_phone;
    245         }
    246        
    247         rc = socket_ports_initialize(&tcp_globals.sockets);
    248         if (rc != EOK)
    249                 goto out;
    250 
    251         rc = packet_dimensions_initialize(&tcp_globals.dimensions);
    252         if (rc != EOK) {
    253                 socket_ports_destroy(&tcp_globals.sockets);
    254                 goto out;
    255         }
    256 
    257         tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
    258 
    259 out:
    260         fibril_rwlock_write_unlock(&tcp_globals.lock);
    261         return rc;
    262 }
    263220
    264221int tcp_received_msg(device_id_t device_id, packet_t *packet,
     
    357314        /* Find the destination socket */
    358315        socket = socket_port_find(&tcp_globals.sockets,
    359             ntohs(header->destination_port), (const char *) src, addrlen);
     316            ntohs(header->destination_port), (uint8_t *) src, addrlen);
    360317        if (!socket) {
    361318                /* Find the listening destination socket */
    362319                socket = socket_port_find(&tcp_globals.sockets,
    363                     ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING,
    364                     0);
     320                    ntohs(header->destination_port),
     321                    (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
    365322        }
    366323
     
    453410
    454411has_error_service:
    455         fibril_rwlock_read_unlock(&tcp_globals.lock);
     412        fibril_rwlock_write_unlock(&tcp_globals.lock);
    456413
    457414        /* TODO error reporting/handling */
     
    504461        size_t offset;
    505462        uint32_t new_sequence_number;
     463        bool forced_ack;
    506464        int rc;
    507465
     
    512470        assert(packet);
    513471
     472        forced_ack = false;
     473
    514474        new_sequence_number = ntohl(header->sequence_number);
    515475        old_incoming = socket_data->next_incoming;
    516476
    517         if (header->finalize)
    518                 socket_data->fin_incoming = new_sequence_number;
     477        if (header->finalize) {
     478                socket_data->fin_incoming = new_sequence_number +
     479                    total_length - TCP_HEADER_LENGTH(header);
     480        }
    519481
    520482        /* Trim begining if containing expected data */
     
    760722                /* Release duplicite or restricted */
    761723                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    762         }
    763 
    764         /* Change state according to the acknowledging incoming fin */
    765         if (IS_IN_INTERVAL_OVERFLOW(old_incoming, socket_data->fin_incoming,
    766             socket_data->next_incoming)) {
     724                forced_ack = true;
     725        }
     726
     727        /* If next in sequence is an incoming FIN */
     728        if (socket_data->next_incoming == socket_data->fin_incoming) {
     729                /* Advance sequence number */
     730                socket_data->next_incoming += 1;
     731
     732                /* Handle FIN */
    767733                switch (socket_data->state) {
    768734                case TCP_SOCKET_FIN_WAIT_1:
     
    771737                        socket_data->state = TCP_SOCKET_CLOSING;
    772738                        break;
    773                 /*case TCP_ESTABLISHED:*/
     739                case TCP_SOCKET_ESTABLISHED:
     740                        /* Queue end-of-data marker on the socket. */
     741                        tcp_queue_received_end_of_data(socket);
     742                        socket_data->state = TCP_SOCKET_CLOSE_WAIT;
     743                        break;
    774744                default:
    775745                        socket_data->state = TCP_SOCKET_CLOSE_WAIT;
     
    779749
    780750        packet = tcp_get_packets_to_send(socket, socket_data);
    781         if (!packet) {
     751        if (!packet && (socket_data->next_incoming != old_incoming || forced_ack)) {
    782752                /* Create the notification packet */
    783753                rc = tcp_create_notification_packet(&packet, socket,
     
    835805
    836806        return EOK;
     807}
     808
     809/** Queue end-of-data marker on the socket.
     810 *
     811 * Next element in the sequence space is FIN. Queue end-of-data marker
     812 * on the socket.
     813 *
     814 * @param socket        Socket
     815 */
     816static void tcp_queue_received_end_of_data(socket_core_t *socket)
     817{
     818        assert(socket != NULL);
     819
     820        /* Notify the destination socket */
     821        async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
     822            (sysarg_t) socket->socket_id,
     823            0, 0, 0,
     824            (sysarg_t) 0 /* 0 fragments == no more data */);
    837825}
    838826
     
    966954        /* Find the destination socket */
    967955        listening_socket = socket_port_find(&tcp_globals.sockets,
    968             listening_port, SOCKET_MAP_KEY_LISTENING, 0);
     956            listening_port, (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
    969957        if (!listening_socket ||
    970958            (listening_socket->socket_id != listening_socket_id)) {
     
    990978
    991979        rc = socket_port_add(&tcp_globals.sockets, listening_port, socket,
    992             (const char *) socket_data->addr, socket_data->addrlen);
     980            (uint8_t *) socket_data->addr, socket_data->addrlen);
    993981        assert(socket == socket_port_find(&tcp_globals.sockets, listening_port,
    994             (const char *) socket_data->addr, socket_data->addrlen));
     982            (uint8_t *) socket_data->addr, socket_data->addrlen));
    995983
    996984//      rc = socket_bind_free_port(&tcp_globals.sockets, socket,
     
    12151203}
    12161204
     1205/** Per-connection initialization
     1206 *
     1207 */
     1208void tl_connection(void)
     1209{
     1210}
     1211
    12171212/** Processes the TCP message.
    12181213 *
     
    12281223 * @see IS_NET_TCP_MESSAGE()
    12291224 */
    1230 int
    1231 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    1232     ipc_call_t *answer, int *answer_count)
    1233 {
    1234         packet_t *packet;
    1235         int rc;
    1236 
     1225int tl_message(ipc_callid_t callid, ipc_call_t *call,
     1226    ipc_call_t *answer, size_t *answer_count)
     1227{
    12371228        assert(call);
    12381229        assert(answer);
     
    12411232        *answer_count = 0;
    12421233        switch (IPC_GET_IMETHOD(*call)) {
    1243         case NET_TL_RECEIVED:
    1244 //              fibril_rwlock_read_lock(&tcp_globals.lock);
    1245                 rc = packet_translate_remote(tcp_globals.net_phone, &packet,
    1246                     IPC_GET_PACKET(call));
    1247                 if (rc != EOK) {
    1248 //                      fibril_rwlock_read_unlock(&tcp_globals.lock);
    1249                         return rc;
    1250                 }
    1251                 rc = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP,
    1252                     IPC_GET_ERROR(call));
    1253 //              fibril_rwlock_read_unlock(&tcp_globals.lock);
    1254                 return rc;
    12551234        case IPC_M_CONNECT_TO_ME:
    12561235                return tcp_process_client_messages(callid, *call);
     
    12911270        bool keep_on_going = true;
    12921271        socket_cores_t local_sockets;
    1293         int app_phone = IPC_GET_PHONE(&call);
     1272        int app_phone = IPC_GET_PHONE(call);
    12941273        struct sockaddr *addr;
    12951274        int socket_id;
     
    12981277        fibril_rwlock_t lock;
    12991278        ipc_call_t answer;
    1300         int answer_count;
     1279        size_t answer_count;
    13011280        tcp_socket_data_t *socket_data;
    13021281        socket_core_t *socket;
     
    15261505
    15271506        /* Release the application phone */
    1528         ipc_hangup(app_phone);
     1507        async_hangup(app_phone);
    15291508
    15301509        printf("release\n");
     
    17281707                if (socket->port > 0) {
    17291708                        socket_ports_exclude(&tcp_globals.sockets,
    1730                             socket->port);
     1709                            socket->port, free);
    17311710                        socket->port = 0;
    17321711                }
     
    18031782                        fibril_rwlock_write_unlock(socket_data->local_lock);
    18041783
     1784                        socket_data->state = TCP_SOCKET_SYN_SENT;
     1785
    18051786                        /* Send the packet */
    18061787                        printf("connecting %d\n", packet_get_id(packet));
     
    20752056
    20762057        /* Copy the key */
    2077         operation_timeout->key = ((char *) operation_timeout) +
     2058        operation_timeout->key = ((uint8_t *) operation_timeout) +
    20782059            sizeof(*operation_timeout);
    20792060        operation_timeout->key_length = socket->key_length;
     
    20852066        if (!fibril) {
    20862067                free(operation_timeout);
    2087                 return EPARTY;  /* FIXME: use another EC */
    2088         }
     2068                return ENOMEM;
     2069        }
     2070
    20892071//      fibril_mutex_lock(&socket_data->operation.mutex);
    20902072        /* Start the timeout fibril */
     
    22092191
    22102192                tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
    2211                 rc = tcp_queue_packet(socket, socket_data, packet, 0);
     2193                rc = tcp_queue_packet(socket, socket_data, packet, total_length);
    22122194                if (rc != EOK)
    22132195                        return rc;
     
    24512433}
    24522434
    2453 /** Default thread for new connections.
     2435/** Process IPC messages from the IP module
    24542436 *
    2455  * @param[in] iid       The initial message identifier.
    2456  * @param[in] icall     The initial message call structure.
     2437 * @param[in]     iid   Message identifier.
     2438 * @param[in,out] icall Message parameters.
    24572439 *
    24582440 */
    2459 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
    2460 {
    2461         /*
    2462          * Accept the connection
    2463          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    2464          */
    2465         ipc_answer_0(iid, EOK);
    2466 
     2441static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall)
     2442{
     2443        packet_t *packet;
     2444        int rc;
     2445       
    24672446        while (true) {
    2468                 ipc_call_t answer;
    2469                 int answer_count;
    2470 
    2471                 /* Clear the answer structure */
    2472                 refresh_answer(&answer, &answer_count);
    2473 
    2474                 /* Fetch the next message */
    2475                 ipc_call_t call;
    2476                 ipc_callid_t callid = async_get_call(&call);
    2477 
    2478                 /* Process the message */
    2479                 int res = tl_module_message_standalone(callid, &call, &answer,
    2480                     &answer_count);
    2481 
    2482                 /*
    2483                  * End if told to either by the message or the processing
    2484                  * result.
    2485                  */
    2486                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    2487                     (res == EHANGUP))
    2488                         return;
    2489 
    2490                 /*
    2491                  * Answer the message
    2492                  */
    2493                 answer_call(callid, res, &answer, answer_count);
    2494         }
    2495 }
    2496 
    2497 /** Starts the module.
     2447                switch (IPC_GET_IMETHOD(*icall)) {
     2448                case NET_TL_RECEIVED:
     2449                        rc = packet_translate_remote(tcp_globals.net_phone, &packet,
     2450                            IPC_GET_PACKET(*icall));
     2451                        if (rc == EOK)
     2452                                rc = tcp_received_msg(IPC_GET_DEVICE(*icall), packet,
     2453                                    SERVICE_TCP, IPC_GET_ERROR(*icall));
     2454                       
     2455                        async_answer_0(iid, (sysarg_t) rc);
     2456                        break;
     2457                default:
     2458                        async_answer_0(iid, (sysarg_t) ENOTSUP);
     2459                }
     2460               
     2461                iid = async_get_call(icall);
     2462        }
     2463}
     2464
     2465/** Initialize the TCP module.
    24982466 *
    2499  * @return              EOK on success.
    2500  * @return              Other error codes as defined for each specific module
    2501  *                      start function.
     2467 * @param[in] net_phone Network module phone.
     2468 *
     2469 * @return EOK on success.
     2470 * @return ENOMEM if there is not enough memory left.
     2471 *
    25022472 */
    2503 int
    2504 main(int argc, char *argv[])
    2505 {
    2506         int rc;
    2507 
    2508         rc = tl_module_start_standalone(tl_client_connection);
     2473int tl_initialize(int net_phone)
     2474{
     2475        fibril_rwlock_initialize(&tcp_globals.lock);
     2476        fibril_rwlock_write_lock(&tcp_globals.lock);
     2477       
     2478        tcp_globals.net_phone = net_phone;
     2479       
     2480        tcp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT);
     2481        tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
     2482            SERVICE_TCP, tcp_receiver);
     2483        if (tcp_globals.ip_phone < 0) {
     2484                fibril_rwlock_write_unlock(&tcp_globals.lock);
     2485                return tcp_globals.ip_phone;
     2486        }
     2487       
     2488        int rc = socket_ports_initialize(&tcp_globals.sockets);
     2489        if (rc != EOK)
     2490                goto out;
     2491
     2492        rc = packet_dimensions_initialize(&tcp_globals.dimensions);
     2493        if (rc != EOK) {
     2494                socket_ports_destroy(&tcp_globals.sockets, free);
     2495                goto out;
     2496        }
     2497
     2498        tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
     2499
     2500out:
     2501        fibril_rwlock_write_unlock(&tcp_globals.lock);
    25092502        return rc;
     2503}
     2504
     2505int main(int argc, char *argv[])
     2506{
     2507        return tl_module_start(SERVICE_TCP);
    25102508}
    25112509
Note: See TracChangeset for help on using the changeset viewer.