Ignore:
File:
1 edited

Legend:

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

    r02a09ed r69a93df7  
    4242#include <ipc/services.h>
    4343#include <ipc/socket.h>
     44#include <net/modules.h>
    4445#include <net/socket.h>
    4546#include <ns.h>
     
    5152#include "ucall.h"
    5253
     54#define FRAGMENT_SIZE 1024
     55
    5356#define MAX_BACKLOG 128
    5457
     
    6467static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    6568static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg);
    66 static int tcp_sock_recv_fibril(void *arg);
    6769
    6870int tcp_sock_init(void)
    6971{
     72        int rc;
     73
    7074        socket_ports_initialize(&gsock);
    71        
     75
    7276        async_set_client_connection(tcp_sock_connection);
    73        
    74         int rc = service_register(SERVICE_TCP);
     77
     78        rc = service_register(SERVICE_TCP);
    7579        if (rc != EOK)
    7680                return EEXIST;
    77        
     81
    7882        return EOK;
    7983}
     
    8589        socket = (tcp_sockdata_t *)sock_core->specific_data;
    8690        (void)socket;
    87 
    88         /* XXX We need to initiate connection cleanup here */
    8991}
    9092
    9193static void tcp_sock_notify_data(socket_core_t *sock_core)
    9294{
    93         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_notify_data(%d)", sock_core->socket_id);
     95        log_msg(LVL_DEBUG, "tcp_sock_notify_data(%d)", sock_core->socket_id);
    9496        async_exch_t *exch = async_exchange_begin(sock_core->sess);
    9597        async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
    96             TCP_SOCK_FRAGMENT_SIZE, 0, 0, 1);
     98            FRAGMENT_SIZE, 0, 0, 1);
    9799        async_exchange_end(exch);
    98100}
     
    100102static void tcp_sock_notify_aconn(socket_core_t *lsock_core)
    101103{
    102         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_notify_aconn(%d)", lsock_core->socket_id);
     104        log_msg(LVL_DEBUG, "tcp_sock_notify_aconn(%d)", lsock_core->socket_id);
    103105        async_exch_t *exch = async_exchange_begin(lsock_core->sess);
    104106        async_msg_5(exch, NET_SOCKET_ACCEPTED, (sysarg_t)lsock_core->socket_id,
    105             TCP_SOCK_FRAGMENT_SIZE, 0, 0, 0);
     107            FRAGMENT_SIZE, 0, 0, 0);
    106108        async_exchange_end(exch);
    107109}
    108110
    109 static int tcp_sock_create(tcp_client_t *client, tcp_sockdata_t **rsock)
     111static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    110112{
    111113        tcp_sockdata_t *sock;
    112 
    113         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_create()");
    114         *rsock = NULL;
    115 
    116         sock = calloc(1, sizeof(tcp_sockdata_t));
    117         if (sock == NULL)
    118                 return ENOMEM;
    119 
    120         fibril_mutex_initialize(&sock->lock);
    121         sock->client = client;
    122 
    123         sock->recv_buffer_used = 0;
    124         sock->recv_error = TCP_EOK;
    125         fibril_mutex_initialize(&sock->recv_buffer_lock);
    126         fibril_condvar_initialize(&sock->recv_buffer_cv);
    127         list_initialize(&sock->ready);
    128 
    129         *rsock = sock;
    130         return EOK;
    131 }
    132 
    133 static void tcp_sock_uncreate(tcp_sockdata_t *sock)
    134 {
    135         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_uncreate()");
    136         free(sock);
    137 }
    138 
    139 static int tcp_sock_finish_setup(tcp_sockdata_t *sock, int *sock_id)
    140 {
    141114        socket_core_t *sock_core;
    142         int rc;
    143 
    144         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_finish_setup()");
    145 
    146         sock->recv_fibril = fibril_create(tcp_sock_recv_fibril, sock);
    147         if (sock->recv_fibril == 0)
    148                 return ENOMEM;
    149 
    150         rc = socket_create(&sock->client->sockets, sock->client->sess,
    151             sock, sock_id);
    152 
    153         if (rc != EOK) {
    154                 fibril_destroy(sock->recv_fibril);
    155                 sock->recv_fibril = 0;
    156                 return rc;
    157         }
    158 
    159         sock_core = socket_cores_find(&sock->client->sockets, *sock_id);
    160         assert(sock_core != NULL);
    161         sock->sock_core = sock_core;
    162 
    163         return EOK;
    164 }
    165 
    166 static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    167 {
    168         tcp_sockdata_t *sock;
    169115        int sock_id;
    170116        int rc;
    171117        ipc_call_t answer;
    172118
    173         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_socket()");
    174 
    175         rc = tcp_sock_create(client, &sock);
     119        log_msg(LVL_DEBUG, "tcp_sock_socket()");
     120        sock = calloc(sizeof(tcp_sockdata_t), 1);
     121        if (sock == NULL) {
     122                async_answer_0(callid, ENOMEM);
     123                return;
     124        }
     125
     126        fibril_mutex_initialize(&sock->lock);
     127        sock->client = client;
     128        sock->laddr.ipv4 = TCP_IPV4_ANY;
     129        sock->lconn = NULL;
     130        sock->backlog = 0;
     131        list_initialize(&sock->ready);
     132
     133        sock_id = SOCKET_GET_SOCKET_ID(call);
     134        rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
    176135        if (rc != EOK) {
    177136                async_answer_0(callid, rc);
     
    179138        }
    180139
    181         inet_addr_any(&sock->laddr);
    182         sock->lconn = NULL;
    183         sock->backlog = 0;
    184 
    185         sock_id = SOCKET_GET_SOCKET_ID(call);
    186         rc = tcp_sock_finish_setup(sock, &sock_id);
    187         if (rc != EOK) {
    188                 tcp_sock_uncreate(sock);
    189                 async_answer_0(callid, rc);
    190                 return;
    191         }
    192 
     140        sock_core = socket_cores_find(&client->sockets, sock_id);
     141        assert(sock_core != NULL);
     142        sock->sock_core = sock_core;
     143
     144        refresh_answer(&answer, NULL);
    193145        SOCKET_SET_SOCKET_ID(answer, sock_id);
    194146
    195         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
     147        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    196148        SOCKET_SET_HEADER_SIZE(answer, sizeof(tcp_header_t));
    197        
    198         async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
    199             IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
     149        answer_call(callid, EOK, &answer, 3);
    200150}
    201151
     
    203153{
    204154        int rc;
    205         struct sockaddr_in *addr;
    206         size_t addr_size;
     155        struct sockaddr *addr;
     156        size_t addr_len;
    207157        socket_core_t *sock_core;
    208158        tcp_sockdata_t *socket;
    209        
    210         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_bind()");
    211         log_msg(LOG_DEFAULT, LVL_DEBUG, " - async_data_write_accept");
    212        
    213         addr = NULL;
    214        
    215         rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_size);
     159
     160        log_msg(LVL_DEBUG, "tcp_sock_bind()");
     161        log_msg(LVL_DEBUG, " - async_data_write_accept");
     162        rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len);
    216163        if (rc != EOK) {
    217164                async_answer_0(callid, rc);
    218                 goto out;
    219         }
    220        
    221         if (addr_size != sizeof(struct sockaddr_in)) {
    222                 async_answer_0(callid, EINVAL);
    223                 goto out;
    224         }
    225        
    226         log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_bind");
     165                return;
     166        }
     167
     168        log_msg(LVL_DEBUG, " - call socket_bind");
    227169        rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
    228             addr, addr_size, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
     170            addr, addr_len, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
    229171            last_used_port);
    230172        if (rc != EOK) {
    231173                async_answer_0(callid, rc);
    232                 goto out;
    233         }
    234        
    235         log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_cores_find");
     174                return;
     175        }
     176
     177        log_msg(LVL_DEBUG, " - call socket_cores_find");
    236178        sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call));
    237         if (sock_core == NULL) {
    238                 async_answer_0(callid, ENOENT);
    239                 goto out;
    240         }
    241        
    242         socket = (tcp_sockdata_t *)sock_core->specific_data;
    243         /* XXX Anything to do? */
    244         (void) socket;
    245        
    246         log_msg(LOG_DEFAULT, LVL_DEBUG, " - success");
     179        if (sock_core != NULL) {
     180                socket = (tcp_sockdata_t *)sock_core->specific_data;
     181                /* XXX Anything to do? */
     182                (void) socket;
     183        }
     184
     185        log_msg(LVL_DEBUG, " - success");
    247186        async_answer_0(callid, EOK);
    248        
    249 out:
    250         if (addr != NULL)
    251                 free(addr);
    252187}
    253188
     
    264199        tcp_sock_lconn_t *lconn;
    265200        int i;
    266         int rc;
    267 
    268         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_listen()");
     201
     202        log_msg(LVL_DEBUG, "tcp_sock_listen()");
    269203
    270204        socket_id = SOCKET_GET_SOCKET_ID(call);
     
    284218                return;
    285219        }
    286        
     220
     221        socket = (tcp_sockdata_t *)sock_core->specific_data;
     222
     223        /*
     224         * Prepare @c backlog listening connections.
     225         */
     226        fibril_mutex_lock(&socket->lock);
     227
     228        socket->backlog = backlog;
     229        socket->lconn = calloc(sizeof(tcp_conn_t *), backlog);
     230        if (socket->lconn == NULL) {
     231                fibril_mutex_unlock(&socket->lock);
     232                async_answer_0(callid, ENOMEM);
     233                return;
     234        }
     235
     236        log_msg(LVL_DEBUG, " - open connections");
     237
     238        lsocket.addr.ipv4 = TCP_IPV4_ANY;
     239        lsocket.port = sock_core->port;
     240        fsocket.addr.ipv4 = TCP_IPV4_ANY;
     241        fsocket.port = TCP_PORT_ANY;
     242
     243        for (i = 0; i < backlog; i++) {
     244
     245                lconn = calloc(sizeof(tcp_sock_lconn_t), 1);
     246                if (lconn == NULL) {
     247                        /* XXX Clean up */
     248                        fibril_mutex_unlock(&socket->lock);
     249                        async_answer_0(callid, ENOMEM);
     250                        return;
     251                }
     252
     253                trc = tcp_uc_open(&lsocket, &fsocket, ap_passive,
     254                    tcp_open_nonblock, &conn);
     255                if (conn == NULL) {
     256                        /* XXX Clean up */
     257                        fibril_mutex_unlock(&socket->lock);
     258                        async_answer_0(callid, ENOMEM);
     259                        return;
     260                }
     261
     262                tcp_uc_set_cstate_cb(conn, tcp_sock_cstate_cb, lconn);
     263
     264                assert(trc == TCP_EOK);
     265                conn->name = (char *)"S";
     266
     267                lconn->conn = conn;
     268                lconn->socket = socket;
     269                link_initialize(&lconn->ready_list);
     270                socket->lconn[i] = lconn;
     271        }
     272
     273        fibril_mutex_unlock(&socket->lock);
     274        async_answer_0(callid, EOK);
     275}
     276
     277static void tcp_sock_connect(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
     278{
     279        int rc;
     280        struct sockaddr_in *addr;
     281        int socket_id;
     282        size_t addr_len;
     283        socket_core_t *sock_core;
     284        tcp_sockdata_t *socket;
     285        tcp_error_t trc;
     286        tcp_sock_t lsocket;
     287        tcp_sock_t fsocket;
     288
     289        log_msg(LVL_DEBUG, "tcp_sock_connect()");
     290
     291        rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len);
     292        if (rc != EOK || addr_len != sizeof(struct sockaddr_in)) {
     293                async_answer_0(callid, rc);
     294                return;
     295        }
     296
     297        socket_id = SOCKET_GET_SOCKET_ID(call);
     298
     299        sock_core = socket_cores_find(&client->sockets, socket_id);
     300        if (sock_core == NULL) {
     301                async_answer_0(callid, ENOTSOCK);
     302                return;
     303        }
     304
     305        socket = (tcp_sockdata_t *)sock_core->specific_data;
    287306        if (sock_core->port <= 0) {
    288307                rc = socket_bind_free_port(&gsock, sock_core,
     
    293312                        return;
    294313                }
    295                
     314
    296315                last_used_port = sock_core->port;
    297316        }
    298        
    299         socket = (tcp_sockdata_t *) sock_core->specific_data;
    300        
    301         /*
    302          * Prepare @c backlog listening connections.
    303          */
     317
    304318        fibril_mutex_lock(&socket->lock);
    305        
    306         socket->backlog = backlog;
    307         socket->lconn = calloc(backlog, sizeof(tcp_conn_t *));
    308         if (socket->lconn == NULL) {
    309                 fibril_mutex_unlock(&socket->lock);
    310                 async_answer_0(callid, ENOMEM);
    311                 return;
    312         }
    313        
    314         log_msg(LOG_DEFAULT, LVL_DEBUG, " - open connections");
    315        
    316         inet_addr_any(&lsocket.addr);
    317         lsocket.port = sock_core->port;
    318        
    319         inet_addr_any(&fsocket.addr);
    320         fsocket.port = TCP_PORT_ANY;
    321        
    322         for (i = 0; i < backlog; i++) {
    323 
    324                 lconn = calloc(1, sizeof(tcp_sock_lconn_t));
    325                 if (lconn == NULL) {
    326                         /* XXX Clean up */
    327                         fibril_mutex_unlock(&socket->lock);
    328                         async_answer_0(callid, ENOMEM);
    329                         return;
    330                 }
    331 
    332                 trc = tcp_uc_open(&lsocket, &fsocket, ap_passive,
    333                     tcp_open_nonblock, &conn);
    334                 if (conn == NULL) {
    335                         /* XXX Clean up */
    336                         fibril_mutex_unlock(&socket->lock);
    337                         async_answer_0(callid, ENOMEM);
    338                         return;
    339                 }
    340 
    341                 tcp_uc_set_cstate_cb(conn, tcp_sock_cstate_cb, lconn);
    342 
    343                 assert(trc == TCP_EOK);
    344                 conn->name = (char *)"S";
    345 
    346                 lconn->conn = conn;
    347                 lconn->socket = socket;
    348                 link_initialize(&lconn->ready_list);
    349                 socket->lconn[i] = lconn;
    350         }
    351 
    352         fibril_mutex_unlock(&socket->lock);
    353         async_answer_0(callid, EOK);
    354 }
    355 
    356 static void tcp_sock_connect(tcp_client_t *client, ipc_callid_t callid,
    357     ipc_call_t call)
    358 {
    359         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect()");
    360        
    361         struct sockaddr_in6 *addr6 = NULL;
    362         size_t addr_len;
    363         int rc = async_data_write_accept((void **) &addr6, false, 0, 0, 0, &addr_len);
    364         if (rc != EOK) {
    365                 async_answer_0(callid, rc);
    366                 return;
    367         }
    368        
    369         if ((addr_len != sizeof(struct sockaddr_in)) &&
    370             (addr_len != sizeof(struct sockaddr_in6))) {
    371                 async_answer_0(callid, EINVAL);
    372                 goto out;
    373         }
    374        
    375         struct sockaddr_in *addr = (struct sockaddr_in *) addr6;
    376        
    377         int socket_id = SOCKET_GET_SOCKET_ID(call);
    378         socket_core_t *sock_core = socket_cores_find(&client->sockets,
    379             socket_id);
    380         if (sock_core == NULL) {
    381                 async_answer_0(callid, ENOTSOCK);
    382                 goto out;
    383         }
    384        
    385         tcp_sockdata_t *socket =
    386             (tcp_sockdata_t *) sock_core->specific_data;
    387        
    388         if (sock_core->port <= 0) {
    389                 rc = socket_bind_free_port(&gsock, sock_core,
    390                     TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
    391                     last_used_port);
    392                 if (rc != EOK) {
    393                         async_answer_0(callid, rc);
    394                         goto out;
    395                 }
    396                
    397                 last_used_port = sock_core->port;
    398         }
    399        
    400         fibril_mutex_lock(&socket->lock);
    401        
    402         if (inet_addr_is_any(&socket->laddr)) {
     319
     320        if (socket->laddr.ipv4 == TCP_IPV4_ANY) {
    403321                /* Determine local IP address */
    404                 inet_addr_t loc_addr;
    405                 inet_addr_t rem_addr;
    406                
    407                 switch (addr->sin_family) {
    408                 case AF_INET:
    409                         inet_sockaddr_in_addr(addr, &rem_addr);
    410                         break;
    411                 case AF_INET6:
    412                         inet_sockaddr_in6_addr(addr6, &rem_addr);
    413                         break;
    414                 default:
    415                         fibril_mutex_unlock(&socket->lock);
    416                         async_answer_0(callid, EINVAL);
    417                         goto out;
    418                 }
    419                
     322                inet_addr_t loc_addr, rem_addr;
     323
     324                rem_addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
    420325                rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
    421326                if (rc != EOK) {
    422327                        fibril_mutex_unlock(&socket->lock);
    423328                        async_answer_0(callid, rc);
    424                         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect: Failed to "
     329                        log_msg(LVL_DEBUG, "tcp_sock_connect: Failed to "
    425330                            "determine local address.");
    426                         goto out;
    427                 }
    428                
    429                 socket->laddr = loc_addr;
    430         }
    431        
    432         tcp_sock_t lsocket;
    433         tcp_sock_t fsocket;
    434        
    435         lsocket.addr = socket->laddr;
     331                        return;
     332                }
     333
     334                socket->laddr.ipv4 = loc_addr.ipv4;
     335                log_msg(LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4);
     336        }
     337
     338        lsocket.addr.ipv4 = socket->laddr.ipv4;
    436339        lsocket.port = sock_core->port;
    437        
    438         switch (addr->sin_family) {
    439         case AF_INET:
    440                 inet_sockaddr_in_addr(addr, &fsocket.addr);
    441                 break;
    442         case AF_INET6:
    443                 inet_sockaddr_in6_addr(addr6, &fsocket.addr);
    444                 break;
    445         default:
    446                 fibril_mutex_unlock(&socket->lock);
    447                 async_answer_0(callid, EINVAL);
    448                 goto out;
    449         }
    450        
     340        fsocket.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
    451341        fsocket.port = uint16_t_be2host(addr->sin_port);
    452        
    453         tcp_error_t trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0,
    454             &socket->conn);
    455        
     342
     343        trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn);
     344
    456345        if (socket->conn != NULL)
    457                 socket->conn->name = (char *) "C";
    458        
     346                socket->conn->name = (char *)"C";
     347
    459348        fibril_mutex_unlock(&socket->lock);
    460        
     349
    461350        switch (trc) {
    462351        case TCP_EOK:
     
    469358                assert(false);
    470359        }
    471        
    472         if (rc == EOK)
    473                 fibril_add_ready(socket->recv_fibril);
    474        
     360
    475361        async_answer_0(callid, rc);
    476        
    477 out:
    478         if (addr6 != NULL)
    479                 free(addr6);
     362
     363        /* Push one fragment notification to client's queue */
     364        tcp_sock_notify_data(sock_core);
     365        log_msg(LVL_DEBUG, "tcp_sock_connect(): notify conn\n");
    480366}
    481367
     
    486372        int asock_id;
    487373        socket_core_t *sock_core;
     374        socket_core_t *asock_core;
    488375        tcp_sockdata_t *socket;
    489376        tcp_sockdata_t *asocket;
     
    496383        int rc;
    497384
    498         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept()");
     385        log_msg(LVL_DEBUG, "tcp_sock_accept()");
    499386
    500387        socket_id = SOCKET_GET_SOCKET_ID(call);
     
    506393                return;
    507394        }
    508        
    509         if (sock_core->port <= 0) {
    510                 rc = socket_bind_free_port(&gsock, sock_core,
    511                     TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
    512                     last_used_port);
    513                 if (rc != EOK) {
    514                         async_answer_0(callid, rc);
    515                         return;
    516                 }
    517                
    518                 last_used_port = sock_core->port;
    519         }
    520395
    521396        socket = (tcp_sockdata_t *)sock_core->specific_data;
    522397        fibril_mutex_lock(&socket->lock);
    523398
    524         log_msg(LOG_DEFAULT, LVL_DEBUG, " - verify socket->conn");
     399        log_msg(LVL_DEBUG, " - verify socket->conn");
    525400        if (socket->conn != NULL) {
    526401                fibril_mutex_unlock(&socket->lock);
     
    544419        /* Replenish listening connection */
    545420
    546         inet_addr_any(&lsocket.addr);
     421        lsocket.addr.ipv4 = TCP_IPV4_ANY;
    547422        lsocket.port = sock_core->port;
    548        
    549         inet_addr_any(&fsocket.addr);
     423        fsocket.addr.ipv4 = TCP_IPV4_ANY;
    550424        fsocket.port = TCP_PORT_ANY;
    551425
     
    568442        /* Allocate socket for accepted connection */
    569443
    570         rc = tcp_sock_create(client, &asocket);
     444        log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n");
     445        asocket = calloc(sizeof(tcp_sockdata_t), 1);
     446        if (asocket == NULL) {
     447                fibril_mutex_unlock(&socket->lock);
     448                async_answer_0(callid, ENOMEM);
     449                return;
     450        }
     451
     452        fibril_mutex_initialize(&asocket->lock);
     453        asocket->client = client;
     454        asocket->conn = conn;
     455        log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n");
     456
     457        rc = socket_create(&client->sockets, client->sess, asocket, &asock_id);
    571458        if (rc != EOK) {
    572459                fibril_mutex_unlock(&socket->lock);
     
    574461                return;
    575462        }
    576 
    577         asocket->conn = conn;
    578         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept():create asocket\n");
    579 
    580         rc = tcp_sock_finish_setup(asocket, &asock_id);
    581         if (rc != EOK) {
    582                 tcp_sock_uncreate(asocket);
    583                 fibril_mutex_unlock(&socket->lock);
    584                 async_answer_0(callid, rc);
    585                 return;
    586         }
    587 
    588         fibril_add_ready(asocket->recv_fibril);
    589 
    590         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept(): find acore\n");
    591 
    592         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
     463        log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n");
     464
     465        asock_core = socket_cores_find(&client->sockets, asock_id);
     466        assert(asock_core != NULL);
     467
     468        refresh_answer(&answer, NULL);
     469
     470        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    593471        SOCKET_SET_SOCKET_ID(answer, asock_id);
    594472        SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in));
    595        
    596         async_answer_3(callid, asocket->sock_core->socket_id,
    597             IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    598             IPC_GET_ARG3(answer));
    599        
     473
     474        answer_call(callid, asock_core->socket_id, &answer, 3);
     475
    600476        /* Push one fragment notification to client's queue */
    601         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept(): notify data\n");
     477        log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n");
     478        tcp_sock_notify_data(asock_core);
    602479        fibril_mutex_unlock(&socket->lock);
    603480}
     
    613490        ipc_callid_t wcallid;
    614491        size_t length;
    615         uint8_t buffer[TCP_SOCK_FRAGMENT_SIZE];
     492        uint8_t buffer[FRAGMENT_SIZE];
    616493        tcp_error_t trc;
    617494        int rc;
    618495
    619         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_send()");
     496        log_msg(LVL_DEBUG, "tcp_sock_send()");
    620497        socket_id = SOCKET_GET_SOCKET_ID(call);
    621498        fragments = SOCKET_GET_DATA_FRAGMENTS(call);
     
    644521                }
    645522
    646                 if (length > TCP_SOCK_FRAGMENT_SIZE)
    647                         length = TCP_SOCK_FRAGMENT_SIZE;
     523                if (length > FRAGMENT_SIZE)
     524                        length = FRAGMENT_SIZE;
    648525
    649526                rc = async_data_write_finalize(wcallid, buffer, length);
     
    680557        }
    681558
    682         IPC_SET_ARG1(answer, 0);
    683         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
    684         async_answer_2(callid, EOK, IPC_GET_ARG1(answer),
    685             IPC_GET_ARG2(answer));
     559        refresh_answer(&answer, NULL);
     560        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
     561        answer_call(callid, EOK, &answer, 2);
    686562        fibril_mutex_unlock(&socket->lock);
    687563}
     
    689565static void tcp_sock_sendto(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    690566{
    691         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_sendto()");
     567        log_msg(LVL_DEBUG, "tcp_sock_sendto()");
    692568        async_answer_0(callid, ENOTSUP);
    693569}
     
    695571static void tcp_sock_recvfrom(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    696572{
    697         log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: tcp_sock_recv[from]()", client);
    698        
    699         int socket_id = SOCKET_GET_SOCKET_ID(call);
    700        
    701         socket_core_t *sock_core =
    702             socket_cores_find(&client->sockets, socket_id);
     573        int socket_id;
     574        int flags;
     575        size_t addr_length, length;
     576        socket_core_t *sock_core;
     577        tcp_sockdata_t *socket;
     578        ipc_call_t answer;
     579        ipc_callid_t rcallid;
     580        uint8_t buffer[FRAGMENT_SIZE];
     581        size_t data_len;
     582        xflags_t xflags;
     583        tcp_error_t trc;
     584        struct sockaddr_in addr;
     585        tcp_sock_t *rsock;
     586        int rc;
     587
     588        log_msg(LVL_DEBUG, "%p: tcp_sock_recv[from]()", client);
     589
     590        socket_id = SOCKET_GET_SOCKET_ID(call);
     591        flags = SOCKET_GET_FLAGS(call);
     592
     593        sock_core = socket_cores_find(&client->sockets, socket_id);
    703594        if (sock_core == NULL) {
    704595                async_answer_0(callid, ENOTSOCK);
    705596                return;
    706597        }
    707        
    708         tcp_sockdata_t *socket =
    709             (tcp_sockdata_t *) sock_core->specific_data;
    710        
     598
     599        socket = (tcp_sockdata_t *)sock_core->specific_data;
    711600        fibril_mutex_lock(&socket->lock);
    712        
     601
    713602        if (socket->conn == NULL) {
    714603                fibril_mutex_unlock(&socket->lock);
     
    716605                return;
    717606        }
    718        
    719         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recvfrom(): lock recv_buffer_lock");
    720        
    721         fibril_mutex_lock(&socket->recv_buffer_lock);
    722         while ((socket->recv_buffer_used == 0) &&
    723             (socket->recv_error == TCP_EOK)) {
    724                 log_msg(LOG_DEFAULT, LVL_DEBUG, "wait for recv_buffer_cv + recv_buffer_used != 0");
    725                 fibril_condvar_wait(&socket->recv_buffer_cv,
    726                     &socket->recv_buffer_lock);
    727         }
    728        
    729         log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer");
    730        
    731         size_t data_len = socket->recv_buffer_used;
    732         tcp_error_t trc = socket->recv_error;
    733         int rc;
    734        
     607
     608        (void)flags;
     609
     610        trc = tcp_uc_receive(socket->conn, buffer, FRAGMENT_SIZE, &data_len,
     611            &xflags);
     612        log_msg(LVL_DEBUG, "**** tcp_uc_receive done");
     613
    735614        switch (trc) {
    736615        case TCP_EOK:
     
    747626                assert(false);
    748627        }
    749        
    750         log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv result -> %d", rc);
    751        
     628
     629        log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc);
    752630        if (rc != EOK) {
    753                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    754631                fibril_mutex_unlock(&socket->lock);
    755632                async_answer_0(callid, rc);
    756633                return;
    757634        }
    758        
    759         ipc_callid_t rcallid;
    760        
     635
    761636        if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) {
    762                 /* Fill address */
    763                 tcp_sock_t *rsock = &socket->conn->ident.foreign;
    764                 struct sockaddr_in addr;
    765                 struct sockaddr_in6 addr6;
    766                 size_t addr_length;
    767                
    768                 uint16_t addr_af = inet_addr_sockaddr_in(&rsock->addr, &addr,
    769                     &addr6);
    770                
    771                 switch (addr_af) {
    772                 case AF_INET:
    773                         addr.sin_port = host2uint16_t_be(rsock->port);
    774                        
    775                         log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
    776                         if (!async_data_read_receive(&rcallid, &addr_length)) {
    777                                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    778                                 fibril_mutex_unlock(&socket->lock);
    779                                 async_answer_0(callid, EINVAL);
    780                                 return;
    781                         }
    782                        
    783                         if (addr_length > sizeof(addr))
    784                                 addr_length = sizeof(addr);
    785                        
    786                         log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
    787                         rc = async_data_read_finalize(rcallid, &addr, addr_length);
    788                         if (rc != EOK) {
    789                                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    790                                 fibril_mutex_unlock(&socket->lock);
    791                                 async_answer_0(callid, EINVAL);
    792                                 return;
    793                         }
    794                        
    795                         break;
    796                 case AF_INET6:
    797                         addr6.sin6_port = host2uint16_t_be(rsock->port);
    798                        
    799                         log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read receive");
    800                         if (!async_data_read_receive(&rcallid, &addr_length)) {
    801                                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    802                                 fibril_mutex_unlock(&socket->lock);
    803                                 async_answer_0(callid, EINVAL);
    804                                 return;
    805                         }
    806                        
    807                         if (addr_length > sizeof(addr6))
    808                                 addr_length = sizeof(addr6);
    809                        
    810                         log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read finalize");
    811                         rc = async_data_read_finalize(rcallid, &addr6, addr_length);
    812                         if (rc != EOK) {
    813                                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    814                                 fibril_mutex_unlock(&socket->lock);
    815                                 async_answer_0(callid, EINVAL);
    816                                 return;
    817                         }
    818                        
    819                         break;
    820                 default:
    821                         fibril_mutex_unlock(&socket->recv_buffer_lock);
     637                /* Fill addr */
     638                rsock = &socket->conn->ident.foreign;
     639                addr.sin_family = AF_INET;
     640                addr.sin_addr.s_addr = host2uint32_t_be(rsock->addr.ipv4);
     641                addr.sin_port = host2uint16_t_be(rsock->port);
     642
     643                log_msg(LVL_DEBUG, "addr read receive");
     644                if (!async_data_read_receive(&rcallid, &addr_length)) {
    822645                        fibril_mutex_unlock(&socket->lock);
    823646                        async_answer_0(callid, EINVAL);
    824647                        return;
    825648                }
    826         }
    827        
    828         log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive");
    829        
    830         size_t length;
     649
     650                if (addr_length > sizeof(addr))
     651                        addr_length = sizeof(addr);
     652
     653                log_msg(LVL_DEBUG, "addr read finalize");
     654                rc = async_data_read_finalize(rcallid, &addr, addr_length);
     655                if (rc != EOK) {
     656                        fibril_mutex_unlock(&socket->lock);
     657                        async_answer_0(callid, EINVAL);
     658                        return;
     659                }
     660        }
     661
     662        log_msg(LVL_DEBUG, "data read receive");
    831663        if (!async_data_read_receive(&rcallid, &length)) {
    832                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    833664                fibril_mutex_unlock(&socket->lock);
    834665                async_answer_0(callid, EINVAL);
    835666                return;
    836667        }
    837        
     668
    838669        if (length > data_len)
    839670                length = data_len;
    840        
    841         log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize");
    842        
    843         rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
    844        
    845         socket->recv_buffer_used -= length;
    846        
    847         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recvfrom: %zu left in buffer",
    848             socket->recv_buffer_used);
    849        
    850         if (socket->recv_buffer_used > 0) {
    851                 memmove(socket->recv_buffer, socket->recv_buffer + length,
    852                     socket->recv_buffer_used);
    853                 tcp_sock_notify_data(socket->sock_core);
    854         }
    855        
    856         fibril_condvar_broadcast(&socket->recv_buffer_cv);
    857        
    858         if ((length < data_len) && (rc == EOK))
     671
     672        log_msg(LVL_DEBUG, "data read finalize");
     673        rc = async_data_read_finalize(rcallid, buffer, length);
     674
     675        if (length < data_len && rc == EOK)
    859676                rc = EOVERFLOW;
    860        
    861         ipc_call_t answer;
    862        
     677
    863678        SOCKET_SET_READ_DATA_LENGTH(answer, length);
    864         async_answer_1(callid, EOK, IPC_GET_ARG1(answer));
    865        
    866         fibril_mutex_unlock(&socket->recv_buffer_lock);
     679        answer_call(callid, EOK, &answer, 1);
     680
     681        /* Push one fragment notification to client's queue */
     682        tcp_sock_notify_data(sock_core);
    867683        fibril_mutex_unlock(&socket->lock);
    868684}
     
    875691        tcp_error_t trc;
    876692        int rc;
    877 
    878         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close()");
     693        uint8_t buffer[FRAGMENT_SIZE];
     694        size_t data_len;
     695        xflags_t xflags;
     696
     697        log_msg(LVL_DEBUG, "tcp_sock_close()");
    879698        socket_id = SOCKET_GET_SOCKET_ID(call);
    880699
     
    895714                        return;
    896715                }
    897         }
    898 
    899         /* Grab recv_buffer_lock because of CV wait in tcp_sock_recv_fibril() */
    900         fibril_mutex_lock(&socket->recv_buffer_lock);
    901         socket->sock_core = NULL;
    902         fibril_mutex_unlock(&socket->recv_buffer_lock);
     716
     717                /* Drain incoming data. This should really be done in the background. */
     718                do {
     719                        trc = tcp_uc_receive(socket->conn, buffer,
     720                            FRAGMENT_SIZE, &data_len, &xflags);
     721                } while (trc == TCP_EOK);
     722
     723                tcp_uc_delete(socket->conn);
     724        }
    903725
    904726        rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock,
     
    916738static void tcp_sock_getsockopt(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    917739{
    918         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_getsockopt()");
     740        log_msg(LVL_DEBUG, "tcp_sock_getsockopt()");
    919741        async_answer_0(callid, ENOTSUP);
    920742}
     
    922744static void tcp_sock_setsockopt(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    923745{
    924         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_setsockopt()");
     746        log_msg(LVL_DEBUG, "tcp_sock_setsockopt()");
    925747        async_answer_0(callid, ENOTSUP);
    926748}
     
    933755        tcp_sockdata_t *socket = lconn->socket;
    934756
    935         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_cstate_cb()");
     757        log_msg(LVL_DEBUG, "tcp_sock_cstate_cb()");
    936758        fibril_mutex_lock(&socket->lock);
    937759        assert(conn == lconn->conn);
     
    946768        list_append(&lconn->ready_list, &socket->ready);
    947769
    948         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept");
     770        log_msg(LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept");
    949771
    950772        /* Push one accept notification to client's queue */
     
    953775}
    954776
    955 static int tcp_sock_recv_fibril(void *arg)
    956 {
    957         tcp_sockdata_t *sock = (tcp_sockdata_t *)arg;
    958         size_t data_len;
    959         xflags_t xflags;
    960         tcp_error_t trc;
    961 
    962         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recv_fibril()");
    963 
    964         fibril_mutex_lock(&sock->recv_buffer_lock);
    965 
    966         while (true) {
    967                 log_msg(LOG_DEFAULT, LVL_DEBUG, "call tcp_uc_receive()");
    968                 while (sock->recv_buffer_used != 0 && sock->sock_core != NULL)
    969                         fibril_condvar_wait(&sock->recv_buffer_cv,
    970                             &sock->recv_buffer_lock);
    971 
    972                 trc = tcp_uc_receive(sock->conn, sock->recv_buffer,
    973                     TCP_SOCK_FRAGMENT_SIZE, &data_len, &xflags);
    974 
    975                 if (trc != TCP_EOK) {
    976                         sock->recv_error = trc;
    977                         fibril_condvar_broadcast(&sock->recv_buffer_cv);
    978                         if (sock->sock_core != NULL)
    979                                 tcp_sock_notify_data(sock->sock_core);
    980                         break;
    981                 }
    982 
    983                 log_msg(LOG_DEFAULT, LVL_DEBUG, "got data - broadcast recv_buffer_cv");
    984 
    985                 sock->recv_buffer_used = data_len;
    986                 fibril_condvar_broadcast(&sock->recv_buffer_cv);
    987                 if (sock->sock_core != NULL)
    988                         tcp_sock_notify_data(sock->sock_core);
    989         }
    990 
    991         fibril_mutex_unlock(&sock->recv_buffer_lock);
    992 
    993         tcp_uc_delete(sock->conn);
    994 
    995         return 0;
    996 }
    997 
    998777static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    999778{
     
    1013792                        break;
    1014793
    1015                 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connection: METHOD=%d\n",
     794                log_msg(LVL_DEBUG, "tcp_sock_connection: METHOD=%d\n",
    1016795                    (int)IPC_GET_IMETHOD(call));
    1017796
     
    1056835                }
    1057836        }
    1058 
    1059         /* Clean up */
    1060         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connection: Clean up");
    1061         async_hangup(client.sess);
    1062         socket_cores_release(NULL, &client.sockets, &gsock, tcp_free_sock_data);
    1063837}
    1064838
Note: See TracChangeset for help on using the changeset viewer.