Ignore:
File:
1 edited

Legend:

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

    rffa2c8ef r46d4d9f  
    3636 */
    3737
     38#include "tcp.h"
     39#include "tcp_header.h"
     40#include "tcp_module.h"
     41
    3842#include <assert.h>
    3943#include <async.h>
     
    4448#include <errno.h>
    4549
     50#include <ipc/ipc.h>
    4651#include <ipc/services.h>
    4752#include <ipc/net.h>
     
    6368#include <ip_interface.h>
    6469#include <icmp_client.h>
    65 #include <icmp_remote.h>
     70#include <icmp_interface.h>
    6671#include <net_interface.h>
    6772#include <socket_core.h>
    6873#include <tl_common.h>
    69 #include <tl_remote.h>
    70 #include <tl_skel.h>
    71 
    72 #include "tcp.h"
    73 #include "tcp_header.h"
     74#include <tl_local.h>
     75#include <tl_interface.h>
    7476
    7577/** TCP module name. */
    76 #define NAME  "tcp"
     78#define NAME    "TCP protocol"
    7779
    7880/** The TCP window default value. */
     
    152154
    153155        /** Port map key. */
    154         uint8_t *key;
     156        char *key;
    155157
    156158        /** Port map key length. */
     
    203205static int tcp_queue_received_packet(socket_core_t *, tcp_socket_data_t *,
    204206    packet_t *, int, size_t);
    205 static void tcp_queue_received_end_of_data(socket_core_t *socket);
    206207
    207208static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t);
     
    218219/** TCP global data. */
    219220tcp_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 */
     229int 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
     259out:
     260        fibril_rwlock_write_unlock(&tcp_globals.lock);
     261        return rc;
     262}
    220263
    221264int tcp_received_msg(device_id_t device_id, packet_t *packet,
     
    314357        /* Find the destination socket */
    315358        socket = socket_port_find(&tcp_globals.sockets,
    316             ntohs(header->destination_port), (uint8_t *) src, addrlen);
     359            ntohs(header->destination_port), (const char *) src, addrlen);
    317360        if (!socket) {
    318361                /* Find the listening destination socket */
    319362                socket = socket_port_find(&tcp_globals.sockets,
    320                     ntohs(header->destination_port),
    321                     (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
     363                    ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING,
     364                    0);
    322365        }
    323366
     
    410453
    411454has_error_service:
    412         fibril_rwlock_write_unlock(&tcp_globals.lock);
     455        fibril_rwlock_read_unlock(&tcp_globals.lock);
    413456
    414457        /* TODO error reporting/handling */
     
    461504        size_t offset;
    462505        uint32_t new_sequence_number;
    463         bool forced_ack;
    464506        int rc;
    465507
     
    470512        assert(packet);
    471513
    472         forced_ack = false;
    473 
    474514        new_sequence_number = ntohl(header->sequence_number);
    475515        old_incoming = socket_data->next_incoming;
    476516
    477         if (header->finalize) {
    478                 socket_data->fin_incoming = new_sequence_number +
    479                     total_length - TCP_HEADER_LENGTH(header);
    480         }
     517        if (header->finalize)
     518                socket_data->fin_incoming = new_sequence_number;
    481519
    482520        /* Trim begining if containing expected data */
     
    722760                /* Release duplicite or restricted */
    723761                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    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 */
     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)) {
    733767                switch (socket_data->state) {
    734768                case TCP_SOCKET_FIN_WAIT_1:
     
    737771                        socket_data->state = TCP_SOCKET_CLOSING;
    738772                        break;
    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;
     773                /*case TCP_ESTABLISHED:*/
    744774                default:
    745775                        socket_data->state = TCP_SOCKET_CLOSE_WAIT;
     
    749779
    750780        packet = tcp_get_packets_to_send(socket, socket_data);
    751         if (!packet && (socket_data->next_incoming != old_incoming || forced_ack)) {
     781        if (!packet) {
    752782                /* Create the notification packet */
    753783                rc = tcp_create_notification_packet(&packet, socket,
     
    799829        /* Notify the destination socket */
    800830        async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
    801             (sysarg_t) socket->socket_id,
     831            (ipcarg_t) socket->socket_id,
    802832            ((packet_dimension->content < socket_data->data_fragment_size) ?
    803833            packet_dimension->content : socket_data->data_fragment_size), 0, 0,
    804             (sysarg_t) fragments);
     834            (ipcarg_t) fragments);
    805835
    806836        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  */
    816 static 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 */);
    825837}
    826838
     
    954966        /* Find the destination socket */
    955967        listening_socket = socket_port_find(&tcp_globals.sockets,
    956             listening_port, (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
     968            listening_port, SOCKET_MAP_KEY_LISTENING, 0);
    957969        if (!listening_socket ||
    958970            (listening_socket->socket_id != listening_socket_id)) {
     
    978990
    979991        rc = socket_port_add(&tcp_globals.sockets, listening_port, socket,
    980             (uint8_t *) socket_data->addr, socket_data->addrlen);
     992            (const char *) socket_data->addr, socket_data->addrlen);
    981993        assert(socket == socket_port_find(&tcp_globals.sockets, listening_port,
    982             (uint8_t *) socket_data->addr, socket_data->addrlen));
     994            (const char *) socket_data->addr, socket_data->addrlen));
    983995
    984996//      rc = socket_bind_free_port(&tcp_globals.sockets, socket,
     
    10781090                        /* Notify the destination socket */
    10791091                        async_msg_5(socket->phone, NET_SOCKET_ACCEPTED,
    1080                             (sysarg_t) listening_socket->socket_id,
     1092                            (ipcarg_t) listening_socket->socket_id,
    10811093                            socket_data->data_fragment_size, TCP_HEADER_SIZE,
    1082                             0, (sysarg_t) socket->socket_id);
     1094                            0, (ipcarg_t) socket->socket_id);
    10831095
    10841096                        fibril_rwlock_write_unlock(socket_data->local_lock);
     
    12031215}
    12041216
    1205 /** Per-connection initialization
    1206  *
    1207  */
    1208 void tl_connection(void)
    1209 {
    1210 }
    1211 
    12121217/** Processes the TCP message.
    12131218 *
     
    12231228 * @see IS_NET_TCP_MESSAGE()
    12241229 */
    1225 int tl_message(ipc_callid_t callid, ipc_call_t *call,
    1226     ipc_call_t *answer, size_t *answer_count)
    1227 {
     1230int
     1231tcp_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
    12281237        assert(call);
    12291238        assert(answer);
     
    12311240
    12321241        *answer_count = 0;
    1233         switch (IPC_GET_IMETHOD(*call)) {
     1242        switch (IPC_GET_METHOD(*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;
    12341255        case IPC_M_CONNECT_TO_ME:
    12351256                return tcp_process_client_messages(callid, *call);
     
    12701291        bool keep_on_going = true;
    12711292        socket_cores_t local_sockets;
    1272         int app_phone = IPC_GET_PHONE(call);
     1293        int app_phone = IPC_GET_PHONE(&call);
    12731294        struct sockaddr *addr;
    12741295        int socket_id;
     
    12771298        fibril_rwlock_t lock;
    12781299        ipc_call_t answer;
    1279         size_t answer_count;
     1300        int answer_count;
    12801301        tcp_socket_data_t *socket_data;
    12811302        socket_core_t *socket;
     
    13021323
    13031324                /* Process the call */
    1304                 switch (IPC_GET_IMETHOD(call)) {
     1325                switch (IPC_GET_METHOD(call)) {
    13051326                case IPC_M_PHONE_HUNGUP:
    13061327                        keep_on_going = false;
     
    13441365
    13451366                case NET_SOCKET_BIND:
    1346                         res = async_data_write_accept((void **) &addr, false,
    1347                             0, 0, 0, &addrlen);
     1367                        res = data_receive((void **) &addr, &addrlen);
    13481368                        if (res != EOK)
    13491369                                break;
     
    13821402
    13831403                case NET_SOCKET_CONNECT:
    1384                         res = async_data_write_accept((void **) &addr, false,
    1385                             0, 0, 0, &addrlen);
     1404                        res = data_receive((void **) &addr, &addrlen);
    13861405                        if (res != EOK)
    13871406                                break;
     
    14341453
    14351454                case NET_SOCKET_SENDTO:
    1436                         res = async_data_write_accept((void **) &addr, false,
    1437                             0, 0, 0, &addrlen);
     1455                        res = data_receive((void **) &addr, &addrlen);
    14381456                        if (res != EOK)
    14391457                                break;
     
    15051523
    15061524        /* Release the application phone */
    1507         async_hangup(app_phone);
     1525        ipc_hangup(app_phone);
    15081526
    15091527        printf("release\n");
     
    17821800                        fibril_rwlock_write_unlock(socket_data->local_lock);
    17831801
    1784                         socket_data->state = TCP_SOCKET_SYN_SENT;
    1785 
    17861802                        /* Send the packet */
    17871803                        printf("connecting %d\n", packet_get_id(packet));
     
    20562072
    20572073        /* Copy the key */
    2058         operation_timeout->key = ((uint8_t *) operation_timeout) +
     2074        operation_timeout->key = ((char *) operation_timeout) +
    20592075            sizeof(*operation_timeout);
    20602076        operation_timeout->key_length = socket->key_length;
     
    20662082        if (!fibril) {
    20672083                free(operation_timeout);
    2068                 return ENOMEM;
    2069         }
    2070 
     2084                return EPARTY;  /* FIXME: use another EC */
     2085        }
    20712086//      fibril_mutex_lock(&socket_data->operation.mutex);
    20722087        /* Start the timeout fibril */
     
    21912206
    21922207                tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
    2193                 rc = tcp_queue_packet(socket, socket_data, packet, total_length);
     2208                rc = tcp_queue_packet(socket, socket_data, packet, 0);
    21942209                if (rc != EOK)
    21952210                        return rc;
     
    24332448}
    24342449
    2435 /** Process IPC messages from the IP module
     2450/** Default thread for new connections.
    24362451 *
    2437  * @param[in]     iid   Message identifier.
    2438  * @param[in,out] icall Message parameters.
     2452 * @param[in] iid       The initial message identifier.
     2453 * @param[in] icall     The initial message call structure.
    24392454 *
    24402455 */
    2441 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall)
    2442 {
    2443         packet_t *packet;
     2456static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
     2457{
     2458        /*
     2459         * Accept the connection
     2460         *  - Answer the first IPC_M_CONNECT_ME_TO call.
     2461         */
     2462        ipc_answer_0(iid, EOK);
     2463
     2464        while (true) {
     2465                ipc_call_t answer;
     2466                int answer_count;
     2467
     2468                /* Clear the answer structure */
     2469                refresh_answer(&answer, &answer_count);
     2470
     2471                /* Fetch the next message */
     2472                ipc_call_t call;
     2473                ipc_callid_t callid = async_get_call(&call);
     2474
     2475                /* Process the message */
     2476                int res = tl_module_message_standalone(callid, &call, &answer,
     2477                    &answer_count);
     2478
     2479                /*
     2480                 * End if told to either by the message or the processing
     2481                 * result.
     2482                 */
     2483                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     2484                    (res == EHANGUP))
     2485                        return;
     2486
     2487                /*
     2488                 * Answer the message
     2489                 */
     2490                answer_call(callid, res, &answer, answer_count);
     2491        }
     2492}
     2493
     2494/** Starts the module.
     2495 *
     2496 * @return              EOK on success.
     2497 * @return              Other error codes as defined for each specific module
     2498 *                      start function.
     2499 */
     2500int
     2501main(int argc, char *argv[])
     2502{
    24442503        int rc;
    2445        
    2446         while (true) {
    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.
    2466  *
    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  *
    2472  */
    2473 int 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);
    2495                 goto out;
    2496         }
    2497 
    2498         tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
    2499 
    2500 out:
    2501         fibril_rwlock_write_unlock(&tcp_globals.lock);
     2504
     2505        rc = tl_module_start_standalone(tl_client_connection);
    25022506        return rc;
    2503 }
    2504 
    2505 int main(int argc, char *argv[])
    2506 {
    2507         return tl_module_start(SERVICE_TCP);
    25082507}
    25092508
Note: See TracChangeset for help on using the changeset viewer.