Changeset b99f6e2 in mainline for uspace/lib/c/generic/inet/tcp.c


Ignore:
Timestamp:
2015-05-11T16:15:54Z (9 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d6ff08a0
Parents:
309469de
Message:

Accepting connections.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/inet/tcp.c

    r309469de rb99f6e2  
    3434
    3535#include <errno.h>
     36#include <fibril.h>
    3637#include <inet/endpoint.h>
    3738#include <inet/tcp.h>
     
    4344
    4445static void tcp_cb_conn(ipc_callid_t, ipc_call_t *, void *);
     46static int tcp_conn_fibril(void *);
     47
     48/** Incoming TCP connection info */
     49typedef struct {
     50        tcp_listener_t *lst;
     51        tcp_conn_t *conn;
     52} tcp_in_conn_t;
    4553
    4654static int tcp_callback_create(tcp_t *tcp)
     
    116124}
    117125
    118 int tcp_conn_create(tcp_t *tcp, inet_ep2_t *epp, tcp_cb_t *cb, void *arg,
     126static int tcp_conn_new(tcp_t *tcp, sysarg_t id, tcp_cb_t *cb, void *arg,
    119127    tcp_conn_t **rconn)
    120128{
    121         async_exch_t *exch;
    122129        tcp_conn_t *conn;
    123         ipc_call_t answer;
    124 
    125         printf("tcp_conn_create()\n");
     130
     131        printf("tcp_conn_new()\n");
    126132
    127133        conn = calloc(1, sizeof(tcp_conn_t));
     
    132138        fibril_mutex_initialize(&conn->lock);
    133139        fibril_condvar_initialize(&conn->cv);
     140
     141        conn->tcp = tcp;
     142        conn->id = id;
     143        conn->cb = cb;
     144        conn->cb_arg = arg;
     145
     146        list_append(&conn->ltcp, &tcp->conn);
     147        *rconn = conn;
     148
     149        return EOK;
     150}
     151
     152int tcp_conn_create(tcp_t *tcp, inet_ep2_t *epp, tcp_cb_t *cb, void *arg,
     153    tcp_conn_t **rconn)
     154{
     155        async_exch_t *exch;
     156        ipc_call_t answer;
     157        sysarg_t conn_id;
     158
     159        printf("tcp_conn_create()\n");
    134160
    135161        exch = async_exchange_begin(tcp->sess);
     
    151177                goto error;
    152178
    153         conn->tcp = tcp;
    154         conn->id = IPC_GET_ARG1(answer);
    155         conn->cb = cb;
    156         conn->cb_arg = arg;
    157 
    158         list_append(&conn->ltcp, &tcp->conn);
    159         *rconn = conn;
     179        conn_id = IPC_GET_ARG1(answer);
     180
     181        rc = tcp_conn_new(tcp, conn_id, cb, arg, rconn);
     182        if (rc != EOK)
     183                return rc;
    160184
    161185        return EOK;
    162186error:
    163         free(conn);
    164187        return (int) rc;
    165188}
     
    265288        free(lst);
    266289        (void) rc;
     290}
     291
     292static int tcp_listener_get(tcp_t *tcp, sysarg_t id, tcp_listener_t **rlst)
     293{
     294        list_foreach(tcp->listener, ltcp, tcp_listener_t, lst) {
     295                if (lst->id == id) {
     296                        *rlst = lst;
     297                        return EOK;
     298                }
     299        }
     300
     301        return EINVAL;
    267302}
    268303
     
    552587        printf("tcp_ev_urg_data()\n");
    553588        async_answer_0(iid, ENOTSUP);
     589}
     590
     591static void tcp_ev_new_conn(tcp_t *tcp, ipc_callid_t iid, ipc_call_t *icall)
     592{
     593        tcp_listener_t *lst;
     594        tcp_conn_t *conn;
     595        sysarg_t lst_id;
     596        sysarg_t conn_id;
     597        fid_t fid;
     598        tcp_in_conn_t *cinfo;
     599        int rc;
     600
     601        printf("tcp_ev_new_conn()\n");
     602        lst_id = IPC_GET_ARG1(*icall);
     603        conn_id = IPC_GET_ARG2(*icall);
     604
     605        printf("new conn: lst_id=%zu conn_id=%zu\n", lst_id, conn_id);
     606
     607        rc = tcp_listener_get(tcp, lst_id, &lst);
     608        if (rc != EOK) {
     609                printf("listener ID %zu not found\n",
     610                    lst_id);
     611                async_answer_0(iid, ENOENT);
     612                return;
     613        }
     614
     615        rc = tcp_conn_new(tcp, conn_id, lst->cb, lst->cb_arg, &conn);
     616        if (rc != EOK) {
     617                printf("Failed creating new incoming connection.\n");
     618                async_answer_0(iid, ENOMEM);
     619                return;
     620        }
     621
     622        if (lst->lcb != NULL && lst->lcb->new_conn != NULL) {
     623                printf("Creating connection fibril\n");
     624                cinfo = calloc(1, sizeof(tcp_in_conn_t));
     625                if (cinfo == NULL) {
     626                        printf("Failed creating new incoming connection info.\n");
     627                        async_answer_0(iid, ENOMEM);
     628                        return;
     629                }
     630
     631                cinfo->lst = lst;
     632                cinfo->conn = conn;
     633
     634                fid = fibril_create(tcp_conn_fibril, cinfo);
     635                if (fid == 0) {
     636                        printf("Error creating connection fibril.\n");
     637                        async_answer_0(iid, ENOMEM);
     638                }
     639
     640                fibril_add_ready(fid);
     641        }
     642
     643        async_answer_0(iid, EOK);
    554644}
    555645
     
    589679                        tcp_ev_urg_data(tcp, callid, &call);
    590680                        break;
     681                case TCP_EV_NEW_CONN:
     682                        tcp_ev_new_conn(tcp, callid, &call);
     683                        break;
    591684                default:
    592685                        async_answer_0(callid, ENOTSUP);
     
    596689}
    597690
     691/** Fibril for handling incoming TCP connection in background */
     692static int tcp_conn_fibril(void *arg)
     693{
     694        tcp_in_conn_t *cinfo = (tcp_in_conn_t *)arg;
     695
     696        printf("tcp_conn_fibril: begin\n");
     697        cinfo->lst->lcb->new_conn(cinfo->lst, cinfo->conn);
     698        printf("tcp_conn_fibril: end\n");
     699        tcp_conn_destroy(cinfo->conn);
     700
     701        return EOK;
     702}
    598703
    599704/** @}
Note: See TracChangeset for help on using the changeset viewer.