Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset a4ee3ab2 in mainline


Ignore:
Timestamp:
2011-11-29T22:51:27Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
8fcf74f
Parents:
04cd242
Message:

Implement listen, accept, recvfrom.

Location:
uspace
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/include/errno.h

    r04cd242 ra4ee3ab2  
    9898#define ECONNREFUSED  (-10058)
    9999
     100#define ECONNABORTED  (-10059)
     101
    100102/** The requested operation was not performed. Try again later. */
    101103#define EAGAIN  (-11002)
  • uspace/srv/net/tl/tcp/sock.c

    r04cd242 ra4ee3ab2  
    4141#include <ipc/socket.h>
    4242#include <net/modules.h>
     43#include <net/socket.h>
    4344
    4445#include "sock.h"
     
    5657#define TCP_FREE_PORTS_END              65535
    5758
    58 static int last_used_port;
     59static int last_used_port = TCP_FREE_PORTS_START - 1;
    5960static socket_ports_t gsock;
     61
     62void tcp_sock_init(void)
     63{
     64        socket_ports_initialize(&gsock);
     65}
    6066
    6167static void tcp_free_sock_data(socket_core_t *sock_core)
     
    6975static void tcp_sock_notify_data(socket_core_t *sock_core)
    7076{
     77        log_msg(LVL_DEBUG, "tcp_sock_notify_data(%d)", sock_core->socket_id);
    7178        async_exch_t *exch = async_exchange_begin(sock_core->sess);
    7279        async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
     
    7582}
    7683
     84static void tcp_sock_notify_aconn(socket_core_t *lsock_core)
     85{
     86        log_msg(LVL_DEBUG, "tcp_sock_notify_aconn(%d)", lsock_core->socket_id);
     87        async_exch_t *exch = async_exchange_begin(lsock_core->sess);
     88        async_msg_5(exch, NET_SOCKET_ACCEPTED, (sysarg_t)lsock_core->socket_id,
     89            FRAGMENT_SIZE, 0, 0, 0);
     90        async_exchange_end(exch);
     91}
     92
    7793static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    7894{
     
    115131
    116132        log_msg(LVL_DEBUG, "tcp_sock_bind()");
     133        log_msg(LVL_DEBUG, " - async_data_write_accept");
    117134        rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len);
    118135        if (rc != EOK) {
     
    121138        }
    122139
     140        log_msg(LVL_DEBUG, " - call socket_bind");
    123141        rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
    124142            addr, addr_len, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
     
    129147        }
    130148
     149        log_msg(LVL_DEBUG, " - call socket_cores_find");
    131150        sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call));
    132151        if (sock_core != NULL) {
     
    136155        }
    137156
    138         async_answer_0(callid, ENOTSUP);
     157        log_msg(LVL_DEBUG, " - success");
     158        async_answer_0(callid, EOK);
    139159
    140160        /* Push one fragment notification to client's queue */
     
    166186
    167187        socket = (tcp_sockdata_t *)sock_core->specific_data;
    168         /* XXX Listen */
     188
     189        /*
     190         * XXX We do not do anything and defer action to accept().
     191         * This is a slight difference in semantics, but most servers
     192         * would just listen() and immediately accept() in a loop.
     193         *
     194         * The only difference is that there is a window between
     195         * listen() and accept() or two accept()s where we refuse
     196         * connections.
     197         */
    169198        (void)backlog;
    170199        (void)socket;
    171200
    172         async_answer_0(callid, ENOTSUP);
    173 
    174         /* Push one fragment notification to client's queue */
    175         tcp_sock_notify_data(sock_core);
     201        async_answer_0(callid, EOK);
     202        log_msg(LVL_DEBUG, "tcp_sock_listen(): notify data\n");
     203        /* Push one accept notification to client's queue */
     204        tcp_sock_notify_aconn(sock_core);
    176205}
    177206
     
    205234
    206235        socket = (tcp_sockdata_t *)sock_core->specific_data;
    207 
    208         lport = 1024; /* XXX */
     236        if (sock_core->port <= 0) {
     237                rc = socket_bind_free_port(&gsock, sock_core,
     238                    TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
     239                    last_used_port);
     240                if (rc != EOK) {
     241                        async_answer_0(callid, rc);
     242                        return;
     243                }
     244
     245                last_used_port = sock_core->port;
     246        }
     247
     248        lport = sock_core->port;
    209249        fsocket.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
    210250        fsocket.port = uint16_t_be2host(addr->sin_port);
     
    230270        ipc_call_t answer;
    231271        int socket_id;
    232         int nsocket_id;
     272        int asock_id;
    233273        socket_core_t *sock_core;
    234         tcp_sockdata_t *socket;
     274        socket_core_t *asock_core;
     275        tcp_sockdata_t *socket;
     276        tcp_sockdata_t *asocket;
     277        tcp_error_t trc;
     278        tcp_sock_t fsocket;
     279        tcp_conn_t *conn;
     280        int rc;
    235281
    236282        log_msg(LVL_DEBUG, "tcp_sock_accept()");
    237283
    238284        socket_id = SOCKET_GET_SOCKET_ID(call);
    239         nsocket_id = SOCKET_GET_NEW_SOCKET_ID(call);
     285        asock_id = SOCKET_GET_NEW_SOCKET_ID(call);
    240286
    241287        sock_core = socket_cores_find(&client->sockets, socket_id);
     
    246292
    247293        socket = (tcp_sockdata_t *)sock_core->specific_data;
    248         /* XXX Accept */
    249         (void) socket;
    250         (void) nsocket_id;
    251 /*
     294
     295        log_msg(LVL_DEBUG, " - verify socket->conn");
     296        if (socket->conn != NULL) {
     297                async_answer_0(callid, EINVAL);
     298                return;
     299        }
     300
     301        log_msg(LVL_DEBUG, " - open connection");
     302
     303        fsocket.addr.ipv4 = 0x7f000001; /* XXX */
     304        fsocket.port = 1025; /* XXX */
     305
     306        trc = tcp_uc_open(sock_core->port, &fsocket, ap_passive, &conn);
     307
     308        log_msg(LVL_DEBUG, " - decode TCP return code");
     309
     310        switch (trc) {
     311        case TCP_EOK:
     312                rc = EOK;
     313                break;
     314        case TCP_ERESET:
     315                rc = ECONNABORTED;
     316                break;
     317        default:
     318                assert(false);
     319        }
     320
     321        log_msg(LVL_DEBUG, " - check TCP return code");
     322        if (rc != EOK) {
     323                async_answer_0(callid, rc);
     324                return;
     325        }
     326
     327        log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n");
     328        asocket = calloc(sizeof(tcp_sockdata_t), 1);
     329        if (asocket == NULL) {
     330                async_answer_0(callid, ENOMEM);
     331                return;
     332        }
     333
     334        asocket->client = client;
     335        asocket->conn = conn;
     336        log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n");
     337
     338        rc = socket_create(&client->sockets, client->sess, asocket, &asock_id);
     339        if (rc != EOK) {
     340                async_answer_0(callid, rc);
     341                return;
     342        }
     343        log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n");
     344
     345        asock_core = socket_cores_find(&client->sockets, asock_id);
     346        assert(asock_core != NULL);
     347
    252348        refresh_answer(&answer, NULL);
    253         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size)
    254         ...
    255         async_answer_0(callid, ENOTSUP);*/
    256 
    257         /* TODO */
    258         answer_call(callid, ENOTSUP, &answer, 3);
     349
     350        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
     351        SOCKET_SET_SOCKET_ID(answer, asock_id);
     352        SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in));
     353
     354        answer_call(callid, asock_core->socket_id, &answer, 3);
     355
     356        /* Push one accept notification to client's queue */
     357        tcp_sock_notify_aconn(sock_core);
     358
     359        /* Push one fragment notification to client's queue */
     360        tcp_sock_notify_data(asock_core);
     361        log_msg(LVL_DEBUG, "tcp_sock_listen(): notify aconn\n");
     362
    259363}
    260364
     
    273377        int rc;
    274378
    275         log_msg(LVL_DEBUG, "******** tcp_sock_send() *******************");
     379        log_msg(LVL_DEBUG, "tcp_sock_send()");
    276380        socket_id = SOCKET_GET_SOCKET_ID(call);
    277381        fragments = SOCKET_GET_DATA_FRAGMENTS(call);
     
    338442}
    339443
    340 static void tcp_sock_recv(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
     444static void tcp_sock_recvfrom(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    341445{
    342446        int socket_id;
    343447        int flags;
    344         size_t length;
     448        size_t addr_length, length;
    345449        socket_core_t *sock_core;
    346450        tcp_sockdata_t *socket;
     
    351455        xflags_t xflags;
    352456        tcp_error_t trc;
     457        struct sockaddr_in addr;
     458        tcp_sock_t *rsock;
    353459        int rc;
    354460
    355         log_msg(LVL_DEBUG, "tcp_sock_recv()");
     461        log_msg(LVL_DEBUG, "tcp_sock_recv[from]()");
    356462
    357463        socket_id = SOCKET_GET_SOCKET_ID(call);
     
    365471
    366472        socket = (tcp_sockdata_t *)sock_core->specific_data;
     473        if (socket->conn == NULL) {
     474                async_answer_0(callid, ENOTCONN);
     475                return;
     476        }
    367477
    368478        (void)flags;
     
    370480        trc = tcp_uc_receive(socket->conn, buffer, FRAGMENT_SIZE, &data_len,
    371481            &xflags);
     482        log_msg(LVL_DEBUG, "**** tcp_uc_receive done");
    372483
    373484        switch (trc) {
     
    383494        }
    384495
     496        log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc);
    385497        if (rc != EOK) {
    386498                async_answer_0(callid, rc);
     
    388500        }
    389501
     502        if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) {
     503                /* Fill addr */
     504                rsock = &socket->conn->ident.foreign;
     505                addr.sin_family = AF_INET;
     506                addr.sin_addr.s_addr = host2uint32_t_be(rsock->addr.ipv4);
     507                addr.sin_port = host2uint16_t_be(rsock->port);
     508
     509                log_msg(LVL_DEBUG, "addr read receive");
     510                if (!async_data_read_receive(&rcallid, &addr_length)) {
     511                        async_answer_0(callid, EINVAL);
     512                        return;
     513                }
     514
     515                if (addr_length > sizeof(addr))
     516                        addr_length = sizeof(addr);
     517
     518                log_msg(LVL_DEBUG, "addr read finalize");
     519                rc = async_data_read_finalize(rcallid, &addr, addr_length);
     520                if (rc != EOK) {
     521                        async_answer_0(callid, EINVAL);
     522                        return;
     523                }
     524        }
     525
     526        log_msg(LVL_DEBUG, "data read receive");
    390527        if (!async_data_read_receive(&rcallid, &length)) {
    391528                async_answer_0(callid, EINVAL);
     
    393530        }
    394531
    395         if (length < data_len) {
    396                 async_data_read_finalize(rcallid, buffer, length);
    397                 if (rc == EOK)
    398                         rc = EOVERFLOW;
    399         } else {
     532        if (length > data_len)
    400533                length = data_len;
    401         }
    402 
     534
     535        log_msg(LVL_DEBUG, "data read finalize");
    403536        rc = async_data_read_finalize(rcallid, buffer, length);
    404         length = 0;
     537
     538        if (length < data_len && rc == EOK)
     539                rc = EOVERFLOW;
    405540
    406541        SOCKET_SET_READ_DATA_LENGTH(answer, length);
     
    409544        /* Push one fragment notification to client's queue */
    410545        tcp_sock_notify_data(sock_core);
    411 }
    412 
    413 static void tcp_sock_recvfrom(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    414 {
    415         log_msg(LVL_DEBUG, "tcp_sock_recvfrom()");
    416         async_answer_0(callid, ENOTSUP);
    417546}
    418547
     
    502631                        break;
    503632                case NET_SOCKET_RECV:
    504                         tcp_sock_recv(&client, callid, call);
    505                         break;
    506633                case NET_SOCKET_RECVFROM:
    507634                        tcp_sock_recvfrom(&client, callid, call);
  • uspace/srv/net/tl/tcp/sock.h

    r04cd242 ra4ee3ab2  
    3838#include <async.h>
    3939
     40extern void tcp_sock_init(void);
    4041extern int tcp_sock_connection(async_sess_t *, ipc_callid_t, ipc_call_t);
    4142
  • uspace/srv/net/tl/tcp/tcp.c

    r04cd242 ra4ee3ab2  
    377377        log_msg(LVL_DEBUG, "tl_initialize()");
    378378
     379        tcp_sock_init();
     380
    379381        ip_sess = ip_bind_service(SERVICE_IP, IPPROTO_TCP, SERVICE_TCP,
    380382            tcp_receiver);
  • uspace/srv/net/tl/tcp/test.c

    r04cd242 ra4ee3ab2  
    118118        async_usleep(1000*1000);
    119119
    120         rc = thread_create(test_srv, NULL, "test_srv", &srv_tid);
    121         if (rc != EOK) {
    122                 printf("Failed to create server thread.\n");
    123                 return;
     120        if (0) {
     121                rc = thread_create(test_srv, NULL, "test_srv", &srv_tid);
     122                if (rc != EOK) {
     123                        printf("Failed to create server thread.\n");
     124                        return;
     125                }
    124126        }
    125127
  • uspace/srv/net/tl/tcp/ucall.c

    r04cd242 ra4ee3ab2  
    5757 * XXX We should be able to call active open on an existing listening
    5858 * connection.
     59 * XXX We should be able to get connection structure immediately, before
     60 * establishment.
    5961 */
    6062tcp_error_t tcp_uc_open(uint16_t lport, tcp_sock_t *fsock, acpass_t acpass,
     
    7779                /* Synchronize (initiate) connection */
    7880                tcp_conn_sync(nconn);
    79 
    80                 /* Wait for connection to be established or reset */
    81                 log_msg(LVL_DEBUG, "tcp_uc_open: Wait for connection.");
    82                 fibril_mutex_lock(&nconn->cstate_lock);
    83                 while (nconn->cstate == st_syn_sent ||
    84                     nconn->cstate == st_syn_received) {
    85                         fibril_condvar_wait(&nconn->cstate_cv, &nconn->cstate_lock);
    86                 }
    87                 if (nconn->cstate != st_established) {
    88                         log_msg(LVL_DEBUG, "tcp_uc_open: Connection was reset.");
    89                         assert(nconn->cstate == st_closed);
    90                         fibril_mutex_unlock(&nconn->cstate_lock);
    91                         return TCP_ERESET;
    92                 }
     81        }
     82
     83        /* Wait for connection to be established or reset */
     84        log_msg(LVL_DEBUG, "tcp_uc_open: Wait for connection.");
     85        fibril_mutex_lock(&nconn->cstate_lock);
     86        while (nconn->cstate == st_listen ||
     87            nconn->cstate == st_syn_sent ||
     88            nconn->cstate == st_syn_received) {
     89                fibril_condvar_wait(&nconn->cstate_cv, &nconn->cstate_lock);
     90        }
     91
     92        if (nconn->cstate != st_established) {
     93                log_msg(LVL_DEBUG, "tcp_uc_open: Connection was reset.");
     94                assert(nconn->cstate == st_closed);
    9395                fibril_mutex_unlock(&nconn->cstate_lock);
    94                 log_msg(LVL_DEBUG, "tcp_uc_open: Connection was established.");
    95         }
     96                return TCP_ERESET;
     97        }
     98
     99        fibril_mutex_unlock(&nconn->cstate_lock);
     100        log_msg(LVL_DEBUG, "tcp_uc_open: Connection was established.");
    96101
    97102        *conn = nconn;
Note: See TracChangeset for help on using the changeset viewer.