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

Changeset b99f6e2 in mainline


Ignore:
Timestamp:
2015-05-11T16:15:54Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
d6ff08a0
Parents:
309469de
Message:

Accepting connections.

Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/websrv/websrv.c

    r309469de rb99f6e2  
    142142                rc = tcp_conn_recv_wait(conn, rbuf, BUFFER_SIZE, &nrecv);
    143143                if (rc != EOK) {
    144                         fprintf(stderr, "recv() failed (%d)\n", rc);
     144                        fprintf(stderr, "tcp_conn_recv() failed (%d)\n", rc);
    145145                        return rc;
    146146                }
     
    372372                fprintf(stderr, "Error processing request (%s)\n",
    373373                    str_error(rc));
     374                return;
     375        }
     376
     377        rc = tcp_conn_send_fin(conn);
     378        if (rc != EOK) {
     379                fprintf(stderr, "Error sending FIN.\n");
     380                return;
    374381        }
    375382}
  • 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/** @}
  • uspace/lib/c/include/ipc/tcp.h

    r309469de rb99f6e2  
    5757        TCP_EV_CONN_RESET,
    5858        TCP_EV_DATA,
    59         TCP_EV_URG_DATA
     59        TCP_EV_URG_DATA,
     60        TCP_EV_NEW_CONN
    6061} tcp_event_t;
    61 
    62 typedef enum {
    63         TCP_LEV_NEW_CONN = IPC_FIRST_USER_METHOD
    64 } tcp_listen_event_t;
    6562
    6663#endif
  • uspace/srv/net/tcp/service.c

    r309469de rb99f6e2  
    5959static void tcp_ev_conn_failed(tcp_cconn_t *);
    6060static void tcp_ev_conn_reset(tcp_cconn_t *);
     61static void tcp_ev_new_conn(tcp_clst_t *, tcp_cconn_t *);
    6162
    6263static void tcp_service_cstate_change(tcp_conn_t *, void *, tcp_cstate_t);
    6364static void tcp_service_recv_data(tcp_conn_t *, void *);
     65static void tcp_service_lst_cstate_change(tcp_conn_t *, void *, tcp_cstate_t);
     66
     67static int tcp_cconn_create(tcp_client_t *, tcp_conn_t *, tcp_cconn_t **);
    6468
    6569static tcp_cb_t tcp_service_cb = {
     
    6872};
    6973
     74static tcp_cb_t tcp_service_lst_cb = {
     75        .cstate_change = tcp_service_lst_cstate_change,
     76        .recv_data = NULL
     77};
     78
    7079static void tcp_service_cstate_change(tcp_conn_t *conn, void *arg,
    7180    tcp_cstate_t old_state)
     
    93102}
    94103
     104static void tcp_service_lst_cstate_change(tcp_conn_t *conn, void *arg,
     105    tcp_cstate_t old_state)
     106{
     107        tcp_cstate_t nstate;
     108        tcp_clst_t *clst;
     109        tcp_cconn_t *cconn;
     110        int rc;
     111        tcp_error_t trc;
     112
     113        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_service_lst_cstate_change()");
     114        nstate = conn->cstate;
     115        clst = tcp_uc_get_userptr(conn);
     116
     117        if ((old_state == st_syn_sent || old_state == st_syn_received) &&
     118            (nstate == st_established)) {
     119                /* Connection established */
     120                clst->conn = NULL;
     121
     122                rc = tcp_cconn_create(clst->client, conn, &cconn);
     123                if (rc != EOK) {
     124                        /* XXX Could not create client connection */
     125                        return;
     126                }
     127
     128                /* XXX Is there a race here (i.e. the connection is already active)? */
     129                tcp_uc_set_cb(conn, &tcp_service_cb, cconn);
     130
     131                /* New incoming connection */
     132                tcp_ev_new_conn(clst, cconn);
     133        }
     134
     135        if (old_state != st_closed && nstate == st_closed && conn->reset) {
     136                /* Connection reset */
     137                /* XXX */
     138        }
     139
     140        /* XXX Failed to establish connection */
     141        if (0) {
     142                /* XXX */
     143        }
     144
     145        /* Replenish sentinel connection */
     146
     147        trc = tcp_uc_open(&clst->elocal, NULL, ap_passive, tcp_open_nonblock,
     148            &conn);
     149        if (trc != TCP_EOK) {
     150                /* XXX Could not replenish connection */
     151                return;
     152        }
     153
     154        clst->conn = conn;
     155
     156        /* XXX Is there a race here (i.e. the connection is already active)? */
     157        tcp_uc_set_cb(conn, &tcp_service_lst_cb, clst);
     158}
     159
    95160static void tcp_service_recv_data(tcp_conn_t *conn, void *arg)
    96161{
     
    150215        exch = async_exchange_begin(cconn->client->sess);
    151216        aid_t req = async_send_1(exch, TCP_EV_CONN_RESET, cconn->id, NULL);
     217        async_exchange_end(exch);
     218
     219        async_forget(req);
     220}
     221
     222/** New incoming connection */
     223static void tcp_ev_new_conn(tcp_clst_t *clst, tcp_cconn_t *cconn)
     224{
     225        async_exch_t *exch;
     226
     227        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ev_new_conn()");
     228
     229        exch = async_exchange_begin(clst->client->sess);
     230        aid_t req = async_send_2(exch, TCP_EV_NEW_CONN, clst->id, cconn->id,
     231            NULL);
    152232        async_exchange_end(exch);
    153233
     
    343423        local.port = ep->port;
    344424
    345         trc = tcp_uc_open(&local, NULL, ap_passive, 0, &conn);
     425        trc = tcp_uc_open(&local, NULL, ap_passive, tcp_open_nonblock, &conn);
    346426        if (trc != TCP_EOK)
    347427                return EIO;
     
    354434        }
    355435
    356 //      assoc->cb = &udp_cassoc_cb;
    357 //      assoc->cb_arg = cassoc;
     436        clst->elocal = local;
     437
     438        /* XXX Is there a race here (i.e. the connection is already active)? */
     439        tcp_uc_set_cb(conn, &tcp_service_lst_cb, clst);
    358440
    359441        *rlst_id = clst->id;
  • uspace/srv/net/tcp/tcp_type.h

    r309469de rb99f6e2  
    338338/** TCP client listener */
    339339typedef struct tcp_clst {
     340        /** Local endpoint */
     341        tcp_sock_t elocal;
    340342        /** Connection */
    341343        tcp_conn_t *conn;
Note: See TracChangeset for help on using the changeset viewer.