Ignore:
File:
1 edited

Legend:

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

    r69a93df7 r02a09ed  
    4242#include <ipc/services.h>
    4343#include <ipc/socket.h>
    44 #include <net/modules.h>
    4544#include <net/socket.h>
    4645#include <ns.h>
     
    5251#include "ucall.h"
    5352
    54 #define FRAGMENT_SIZE 1024
    55 
    5653#define MAX_BACKLOG 128
    5754
     
    6764static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    6865static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg);
     66static int tcp_sock_recv_fibril(void *arg);
    6967
    7068int tcp_sock_init(void)
    7169{
    72         int rc;
    73 
    7470        socket_ports_initialize(&gsock);
    75 
     71       
    7672        async_set_client_connection(tcp_sock_connection);
    77 
    78         rc = service_register(SERVICE_TCP);
     73       
     74        int rc = service_register(SERVICE_TCP);
    7975        if (rc != EOK)
    8076                return EEXIST;
    81 
     77       
    8278        return EOK;
    8379}
     
    8985        socket = (tcp_sockdata_t *)sock_core->specific_data;
    9086        (void)socket;
     87
     88        /* XXX We need to initiate connection cleanup here */
    9189}
    9290
    9391static void tcp_sock_notify_data(socket_core_t *sock_core)
    9492{
    95         log_msg(LVL_DEBUG, "tcp_sock_notify_data(%d)", sock_core->socket_id);
     93        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_notify_data(%d)", sock_core->socket_id);
    9694        async_exch_t *exch = async_exchange_begin(sock_core->sess);
    9795        async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
    98             FRAGMENT_SIZE, 0, 0, 1);
     96            TCP_SOCK_FRAGMENT_SIZE, 0, 0, 1);
    9997        async_exchange_end(exch);
    10098}
     
    102100static void tcp_sock_notify_aconn(socket_core_t *lsock_core)
    103101{
    104         log_msg(LVL_DEBUG, "tcp_sock_notify_aconn(%d)", lsock_core->socket_id);
     102        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_notify_aconn(%d)", lsock_core->socket_id);
    105103        async_exch_t *exch = async_exchange_begin(lsock_core->sess);
    106104        async_msg_5(exch, NET_SOCKET_ACCEPTED, (sysarg_t)lsock_core->socket_id,
    107             FRAGMENT_SIZE, 0, 0, 0);
     105            TCP_SOCK_FRAGMENT_SIZE, 0, 0, 0);
    108106        async_exchange_end(exch);
    109107}
    110108
     109static int tcp_sock_create(tcp_client_t *client, tcp_sockdata_t **rsock)
     110{
     111        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
     133static void tcp_sock_uncreate(tcp_sockdata_t *sock)
     134{
     135        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_uncreate()");
     136        free(sock);
     137}
     138
     139static int tcp_sock_finish_setup(tcp_sockdata_t *sock, int *sock_id)
     140{
     141        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
    111166static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    112167{
    113168        tcp_sockdata_t *sock;
    114         socket_core_t *sock_core;
    115169        int sock_id;
    116170        int rc;
    117171        ipc_call_t answer;
    118172
    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;
     173        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_socket()");
     174
     175        rc = tcp_sock_create(client, &sock);
     176        if (rc != EOK) {
     177                async_answer_0(callid, rc);
     178                return;
     179        }
     180
     181        inet_addr_any(&sock->laddr);
    129182        sock->lconn = NULL;
    130183        sock->backlog = 0;
    131         list_initialize(&sock->ready);
    132184
    133185        sock_id = SOCKET_GET_SOCKET_ID(call);
    134         rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
     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
     193        SOCKET_SET_SOCKET_ID(answer, sock_id);
     194
     195        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
     196        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));
     200}
     201
     202static void tcp_sock_bind(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
     203{
     204        int rc;
     205        struct sockaddr_in *addr;
     206        size_t addr_size;
     207        socket_core_t *sock_core;
     208        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);
    135216        if (rc != EOK) {
    136217                async_answer_0(callid, rc);
    137                 return;
    138         }
    139 
    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);
    145         SOCKET_SET_SOCKET_ID(answer, sock_id);
    146 
    147         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    148         SOCKET_SET_HEADER_SIZE(answer, sizeof(tcp_header_t));
    149         answer_call(callid, EOK, &answer, 3);
    150 }
    151 
    152 static void tcp_sock_bind(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    153 {
    154         int rc;
    155         struct sockaddr *addr;
    156         size_t addr_len;
    157         socket_core_t *sock_core;
    158         tcp_sockdata_t *socket;
    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);
    163         if (rc != EOK) {
    164                 async_answer_0(callid, rc);
    165                 return;
    166         }
    167 
    168         log_msg(LVL_DEBUG, " - call socket_bind");
     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");
    169227        rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
    170             addr, addr_len, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
     228            addr, addr_size, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
    171229            last_used_port);
    172230        if (rc != EOK) {
    173231                async_answer_0(callid, rc);
    174                 return;
    175         }
    176 
    177         log_msg(LVL_DEBUG, " - call socket_cores_find");
     232                goto out;
     233        }
     234       
     235        log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_cores_find");
    178236        sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call));
    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");
     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");
    186247        async_answer_0(callid, EOK);
     248       
     249out:
     250        if (addr != NULL)
     251                free(addr);
    187252}
    188253
     
    199264        tcp_sock_lconn_t *lconn;
    200265        int i;
    201 
    202         log_msg(LVL_DEBUG, "tcp_sock_listen()");
     266        int rc;
     267
     268        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_listen()");
    203269
    204270        socket_id = SOCKET_GET_SOCKET_ID(call);
     
    218284                return;
    219285        }
    220 
    221         socket = (tcp_sockdata_t *)sock_core->specific_data;
    222 
     286       
     287        if (sock_core->port <= 0) {
     288                rc = socket_bind_free_port(&gsock, sock_core,
     289                    TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
     290                    last_used_port);
     291                if (rc != EOK) {
     292                        async_answer_0(callid, rc);
     293                        return;
     294                }
     295               
     296                last_used_port = sock_core->port;
     297        }
     298       
     299        socket = (tcp_sockdata_t *) sock_core->specific_data;
     300       
    223301        /*
    224302         * Prepare @c backlog listening connections.
    225303         */
    226304        fibril_mutex_lock(&socket->lock);
    227 
     305       
    228306        socket->backlog = backlog;
    229         socket->lconn = calloc(sizeof(tcp_conn_t *), backlog);
     307        socket->lconn = calloc(backlog, sizeof(tcp_conn_t *));
    230308        if (socket->lconn == NULL) {
    231309                fibril_mutex_unlock(&socket->lock);
     
    233311                return;
    234312        }
    235 
    236         log_msg(LVL_DEBUG, " - open connections");
    237 
    238         lsocket.addr.ipv4 = TCP_IPV4_ANY;
     313       
     314        log_msg(LOG_DEFAULT, LVL_DEBUG, " - open connections");
     315       
     316        inet_addr_any(&lsocket.addr);
    239317        lsocket.port = sock_core->port;
    240         fsocket.addr.ipv4 = TCP_IPV4_ANY;
     318       
     319        inet_addr_any(&fsocket.addr);
    241320        fsocket.port = TCP_PORT_ANY;
    242 
     321       
    243322        for (i = 0; i < backlog; i++) {
    244323
    245                 lconn = calloc(sizeof(tcp_sock_lconn_t), 1);
     324                lconn = calloc(1, sizeof(tcp_sock_lconn_t));
    246325                if (lconn == NULL) {
    247326                        /* XXX Clean up */
     
    275354}
    276355
    277 static 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;
     356static 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;
    282362        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)) {
     363        int rc = async_data_write_accept((void **) &addr6, false, 0, 0, 0, &addr_len);
     364        if (rc != EOK) {
    293365                async_answer_0(callid, rc);
    294366                return;
    295367        }
    296 
    297         socket_id = SOCKET_GET_SOCKET_ID(call);
    298 
    299         sock_core = socket_cores_find(&client->sockets, socket_id);
     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);
    300380        if (sock_core == NULL) {
    301381                async_answer_0(callid, ENOTSOCK);
    302                 return;
    303         }
    304 
    305         socket = (tcp_sockdata_t *)sock_core->specific_data;
     382                goto out;
     383        }
     384       
     385        tcp_sockdata_t *socket =
     386            (tcp_sockdata_t *) sock_core->specific_data;
     387       
    306388        if (sock_core->port <= 0) {
    307389                rc = socket_bind_free_port(&gsock, sock_core,
     
    310392                if (rc != EOK) {
    311393                        async_answer_0(callid, rc);
    312                         return;
    313                 }
    314 
     394                        goto out;
     395                }
     396               
    315397                last_used_port = sock_core->port;
    316398        }
    317 
     399       
    318400        fibril_mutex_lock(&socket->lock);
    319 
    320         if (socket->laddr.ipv4 == TCP_IPV4_ANY) {
     401       
     402        if (inet_addr_is_any(&socket->laddr)) {
    321403                /* Determine local IP address */
    322                 inet_addr_t loc_addr, rem_addr;
    323 
    324                 rem_addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
     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               
    325420                rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
    326421                if (rc != EOK) {
    327422                        fibril_mutex_unlock(&socket->lock);
    328423                        async_answer_0(callid, rc);
    329                         log_msg(LVL_DEBUG, "tcp_sock_connect: Failed to "
     424                        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect: Failed to "
    330425                            "determine local address.");
    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;
     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;
    339436        lsocket.port = sock_core->port;
    340         fsocket.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
     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       
    341451        fsocket.port = uint16_t_be2host(addr->sin_port);
    342 
    343         trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn);
    344 
     452       
     453        tcp_error_t trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0,
     454            &socket->conn);
     455       
    345456        if (socket->conn != NULL)
    346                 socket->conn->name = (char *)"C";
    347 
     457                socket->conn->name = (char *) "C";
     458       
    348459        fibril_mutex_unlock(&socket->lock);
    349 
     460       
    350461        switch (trc) {
    351462        case TCP_EOK:
     
    358469                assert(false);
    359470        }
    360 
     471       
     472        if (rc == EOK)
     473                fibril_add_ready(socket->recv_fibril);
     474       
    361475        async_answer_0(callid, rc);
    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");
     476       
     477out:
     478        if (addr6 != NULL)
     479                free(addr6);
    366480}
    367481
     
    372486        int asock_id;
    373487        socket_core_t *sock_core;
    374         socket_core_t *asock_core;
    375488        tcp_sockdata_t *socket;
    376489        tcp_sockdata_t *asocket;
     
    383496        int rc;
    384497
    385         log_msg(LVL_DEBUG, "tcp_sock_accept()");
     498        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept()");
    386499
    387500        socket_id = SOCKET_GET_SOCKET_ID(call);
     
    393506                return;
    394507        }
     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        }
    395520
    396521        socket = (tcp_sockdata_t *)sock_core->specific_data;
    397522        fibril_mutex_lock(&socket->lock);
    398523
    399         log_msg(LVL_DEBUG, " - verify socket->conn");
     524        log_msg(LOG_DEFAULT, LVL_DEBUG, " - verify socket->conn");
    400525        if (socket->conn != NULL) {
    401526                fibril_mutex_unlock(&socket->lock);
     
    419544        /* Replenish listening connection */
    420545
    421         lsocket.addr.ipv4 = TCP_IPV4_ANY;
     546        inet_addr_any(&lsocket.addr);
    422547        lsocket.port = sock_core->port;
    423         fsocket.addr.ipv4 = TCP_IPV4_ANY;
     548       
     549        inet_addr_any(&fsocket.addr);
    424550        fsocket.port = TCP_PORT_ANY;
    425551
     
    442568        /* Allocate socket for accepted connection */
    443569
    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;
     570        rc = tcp_sock_create(client, &asocket);
     571        if (rc != EOK) {
     572                fibril_mutex_unlock(&socket->lock);
     573                async_answer_0(callid, rc);
     574                return;
     575        }
     576
    454577        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);
     578        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept():create asocket\n");
     579
     580        rc = tcp_sock_finish_setup(asocket, &asock_id);
    458581        if (rc != EOK) {
     582                tcp_sock_uncreate(asocket);
    459583                fibril_mutex_unlock(&socket->lock);
    460584                async_answer_0(callid, rc);
    461585                return;
    462586        }
    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);
     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);
    471593        SOCKET_SET_SOCKET_ID(answer, asock_id);
    472594        SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in));
    473 
    474         answer_call(callid, asock_core->socket_id, &answer, 3);
    475 
     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       
    476600        /* Push one fragment notification to client's queue */
    477         log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n");
    478         tcp_sock_notify_data(asock_core);
     601        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept(): notify data\n");
    479602        fibril_mutex_unlock(&socket->lock);
    480603}
     
    490613        ipc_callid_t wcallid;
    491614        size_t length;
    492         uint8_t buffer[FRAGMENT_SIZE];
     615        uint8_t buffer[TCP_SOCK_FRAGMENT_SIZE];
    493616        tcp_error_t trc;
    494617        int rc;
    495618
    496         log_msg(LVL_DEBUG, "tcp_sock_send()");
     619        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_send()");
    497620        socket_id = SOCKET_GET_SOCKET_ID(call);
    498621        fragments = SOCKET_GET_DATA_FRAGMENTS(call);
     
    521644                }
    522645
    523                 if (length > FRAGMENT_SIZE)
    524                         length = FRAGMENT_SIZE;
     646                if (length > TCP_SOCK_FRAGMENT_SIZE)
     647                        length = TCP_SOCK_FRAGMENT_SIZE;
    525648
    526649                rc = async_data_write_finalize(wcallid, buffer, length);
     
    557680        }
    558681
    559         refresh_answer(&answer, NULL);
    560         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    561         answer_call(callid, EOK, &answer, 2);
     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));
    562686        fibril_mutex_unlock(&socket->lock);
    563687}
     
    565689static void tcp_sock_sendto(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    566690{
    567         log_msg(LVL_DEBUG, "tcp_sock_sendto()");
     691        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_sendto()");
    568692        async_answer_0(callid, ENOTSUP);
    569693}
     
    571695static void tcp_sock_recvfrom(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    572696{
    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);
     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);
    594703        if (sock_core == NULL) {
    595704                async_answer_0(callid, ENOTSOCK);
    596705                return;
    597706        }
    598 
    599         socket = (tcp_sockdata_t *)sock_core->specific_data;
     707       
     708        tcp_sockdata_t *socket =
     709            (tcp_sockdata_t *) sock_core->specific_data;
     710       
    600711        fibril_mutex_lock(&socket->lock);
    601 
     712       
    602713        if (socket->conn == NULL) {
    603714                fibril_mutex_unlock(&socket->lock);
     
    605716                return;
    606717        }
    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 
     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       
    614735        switch (trc) {
    615736        case TCP_EOK:
     
    626747                assert(false);
    627748        }
    628 
    629         log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc);
     749       
     750        log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv result -> %d", rc);
     751       
    630752        if (rc != EOK) {
     753                fibril_mutex_unlock(&socket->recv_buffer_lock);
    631754                fibril_mutex_unlock(&socket->lock);
    632755                async_answer_0(callid, rc);
    633756                return;
    634757        }
    635 
     758       
     759        ipc_callid_t rcallid;
     760       
    636761        if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) {
    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)) {
     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);
    645822                        fibril_mutex_unlock(&socket->lock);
    646823                        async_answer_0(callid, EINVAL);
    647824                        return;
    648825                }
    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");
     826        }
     827       
     828        log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive");
     829       
     830        size_t length;
    663831        if (!async_data_read_receive(&rcallid, &length)) {
     832                fibril_mutex_unlock(&socket->recv_buffer_lock);
    664833                fibril_mutex_unlock(&socket->lock);
    665834                async_answer_0(callid, EINVAL);
    666835                return;
    667836        }
    668 
     837       
    669838        if (length > data_len)
    670839                length = data_len;
    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)
     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))
    676859                rc = EOVERFLOW;
    677 
     860       
     861        ipc_call_t answer;
     862       
    678863        SOCKET_SET_READ_DATA_LENGTH(answer, length);
    679         answer_call(callid, EOK, &answer, 1);
    680 
    681         /* Push one fragment notification to client's queue */
    682         tcp_sock_notify_data(sock_core);
     864        async_answer_1(callid, EOK, IPC_GET_ARG1(answer));
     865       
     866        fibril_mutex_unlock(&socket->recv_buffer_lock);
    683867        fibril_mutex_unlock(&socket->lock);
    684868}
     
    691875        tcp_error_t trc;
    692876        int rc;
    693         uint8_t buffer[FRAGMENT_SIZE];
    694         size_t data_len;
    695         xflags_t xflags;
    696 
    697         log_msg(LVL_DEBUG, "tcp_sock_close()");
     877
     878        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close()");
    698879        socket_id = SOCKET_GET_SOCKET_ID(call);
    699880
     
    714895                        return;
    715896                }
    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         }
     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);
    725903
    726904        rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock,
     
    738916static void tcp_sock_getsockopt(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    739917{
    740         log_msg(LVL_DEBUG, "tcp_sock_getsockopt()");
     918        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_getsockopt()");
    741919        async_answer_0(callid, ENOTSUP);
    742920}
     
    744922static void tcp_sock_setsockopt(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    745923{
    746         log_msg(LVL_DEBUG, "tcp_sock_setsockopt()");
     924        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_setsockopt()");
    747925        async_answer_0(callid, ENOTSUP);
    748926}
     
    755933        tcp_sockdata_t *socket = lconn->socket;
    756934
    757         log_msg(LVL_DEBUG, "tcp_sock_cstate_cb()");
     935        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_cstate_cb()");
    758936        fibril_mutex_lock(&socket->lock);
    759937        assert(conn == lconn->conn);
     
    768946        list_append(&lconn->ready_list, &socket->ready);
    769947
    770         log_msg(LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept");
     948        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept");
    771949
    772950        /* Push one accept notification to client's queue */
     
    775953}
    776954
     955static 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
    777998static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    778999{
     
    7921013                        break;
    7931014
    794                 log_msg(LVL_DEBUG, "tcp_sock_connection: METHOD=%d\n",
     1015                log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connection: METHOD=%d\n",
    7951016                    (int)IPC_GET_IMETHOD(call));
    7961017
     
    8351056                }
    8361057        }
     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);
    8371063}
    8381064
Note: See TracChangeset for help on using the changeset viewer.