Changes in / [a438de48:58f6229] in mainline


Ignore:
Location:
uspace
Files:
8 edited

Legend:

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

    ra438de48 r58f6229  
    304304                if (rc != EOK) {
    305305                        printf("Error closing connection socket: %d\n", rc);
    306                         closesocket(listen_sd);
    307306                        return 1;
    308307                }
  • uspace/srv/net/tl/tcp/conn.c

    ra438de48 r58f6229  
    5656
    5757LIST_INITIALIZE(conn_list);
    58 FIBRIL_MUTEX_INITIALIZE(conn_list_lock);
    5958
    6059static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg);
     
    6261static void tcp_conn_tw_timer_clear(tcp_conn_t *conn);
    6362
    64 /** Create new connection structure.
     63/** Create new segment structure.
    6564 *
    6665 * @param lsock         Local socket (will be deeply copied)
    6766 * @param fsock         Foreign socket (will be deeply copied)
    68  * @return              New connection or NULL
     67 * @return              New segment or NULL
    6968 */
    7069tcp_conn_t *tcp_conn_new(tcp_sock_t *lsock, tcp_sock_t *fsock)
     
    8281                goto error;
    8382
    84         fibril_mutex_initialize(&conn->lock);
    85 
    86         /* One for the user, one for not being in closed state */
    87         atomic_set(&conn->refcnt, 2);
    88 
    8983        /* Allocate receive buffer */
     84        fibril_mutex_initialize(&conn->rcv_buf_lock);
    9085        fibril_condvar_initialize(&conn->rcv_buf_cv);
    9186        conn->rcv_buf_size = RCV_BUF_SIZE;
     
    9893
    9994        /** Allocate send buffer */
    100         fibril_condvar_initialize(&conn->snd_buf_cv);
    10195        conn->snd_buf_size = SND_BUF_SIZE;
    10296        conn->snd_buf_used = 0;
     
    119113
    120114        /* Connection state change signalling */
     115        fibril_mutex_initialize(&conn->cstate_lock);
    121116        fibril_condvar_initialize(&conn->cstate_cv);
    122117
    123118        conn->cstate = st_listen;
    124119        conn->reset = false;
    125         conn->deleted = false;
    126120        conn->ap = ap_passive;
    127121        conn->fin_is_acked = false;
     
    147141}
    148142
    149 /** Destroy connection structure.
    150  *
    151  * Connection structure should be destroyed when the folowing condtitions
    152  * are met:
    153  * (1) user has deleted the connection
    154  * (2) the connection has entered closed state
    155  * (3) nobody is holding references to the connection
    156  *
    157  * This happens when @a conn->refcnt is zero as we count (1) and (2)
    158  * as special references.
    159  *
    160  * @param conn          Connection
    161  */
    162 static void tcp_conn_free(tcp_conn_t *conn)
    163 {
    164         log_msg(LVL_DEBUG, "%s: tcp_conn_free(%p)", conn->name, conn);
    165         tcp_tqueue_fini(&conn->retransmit);
    166 
    167         if (conn->rcv_buf != NULL)
    168                 free(conn->rcv_buf);
    169         if (conn->snd_buf != NULL)
    170                 free(conn->snd_buf);
    171         if (conn->tw_timer != NULL)
    172                 fibril_timer_destroy(conn->tw_timer);
    173         free(conn);
    174 }
    175 
    176 /** Add reference to connection.
    177  *
    178  * Increase connection reference count by one.
    179  *
    180  * @param conn          Connection
    181  */
    182 void tcp_conn_addref(tcp_conn_t *conn)
    183 {
    184         log_msg(LVL_DEBUG, "%s: tcp_conn_addref(%p)", conn->name, conn);
    185         atomic_inc(&conn->refcnt);
    186 }
    187 
    188 /** Remove reference from connection.
    189  *
    190  * Decrease connection reference count by one.
    191  *
    192  * @param conn          Connection
    193  */
    194 void tcp_conn_delref(tcp_conn_t *conn)
    195 {
    196         log_msg(LVL_DEBUG, "%s: tcp_conn_delref(%p)", conn->name, conn);
    197 
    198         if (atomic_predec(&conn->refcnt) == 0)
    199                 tcp_conn_free(conn);
    200 }
    201 
    202 /** Delete connection.
    203  *
    204  * The caller promises not make no further references to @a conn.
    205  * TCP will free @a conn eventually.
    206  *
    207  * @param conn          Connection
    208  */
    209 void tcp_conn_delete(tcp_conn_t *conn)
    210 {
    211         log_msg(LVL_DEBUG, "%s: tcp_conn_delete(%p)", conn->name, conn);
    212 
    213         assert(conn->deleted == false);
    214         tcp_conn_delref(conn);
    215 }
    216 
    217143/** Enlist connection.
    218144 *
     
    221147void tcp_conn_add(tcp_conn_t *conn)
    222148{
    223         tcp_conn_addref(conn);
    224         fibril_mutex_lock(&conn_list_lock);
    225149        list_append(&conn->link, &conn_list);
    226         fibril_mutex_unlock(&conn_list_lock);
    227150}
    228151
     
    233156void tcp_conn_remove(tcp_conn_t *conn)
    234157{
    235         fibril_mutex_lock(&conn_list_lock);
    236158        list_remove(&conn->link);
    237         fibril_mutex_unlock(&conn_list_lock);
    238         tcp_conn_delref(conn);
    239159}
    240160
    241161static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate)
    242162{
    243         tcp_cstate_t old_state;
    244 
    245         old_state = conn->cstate;
     163        fibril_mutex_lock(&conn->cstate_lock);
    246164        conn->cstate = nstate;
    247165        fibril_condvar_broadcast(&conn->cstate_cv);
    248 
    249         assert(old_state != st_closed);
    250         if (nstate == st_closed) {
    251                 /* Drop one reference for now being in closed state */
    252                 tcp_conn_delref(conn);
    253         }
     166        fibril_mutex_unlock(&conn->cstate_lock);
    254167}
    255168
     
    338251 * A connection is uniquely identified by a socket pair. Look up our
    339252 * connection map and return connection structure based on socket pair.
    340  * The connection reference count is bumped by one.
    341253 *
    342254 * @param sp    Socket pair
    343255 * @return      Connection structure or NULL if not found.
    344256 */
    345 tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp)
     257tcp_conn_t *tcp_conn_find(tcp_sockpair_t *sp)
    346258{
    347259        log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp);
    348 
    349         fibril_mutex_lock(&conn_list_lock);
    350260
    351261        list_foreach(conn_list, link) {
     
    356266                    csp->local.addr.ipv4, csp->local.port);
    357267                if (tcp_sockpair_match(sp, csp)) {
    358                         tcp_conn_addref(conn);
    359                         fibril_mutex_unlock(&conn_list_lock);
    360268                        return conn;
    361269                }
    362270        }
    363271
    364         fibril_mutex_unlock(&conn_list_lock);
    365272        return NULL;
    366273}
     
    380287
    381288        fibril_condvar_broadcast(&conn->rcv_buf_cv);
    382         fibril_condvar_broadcast(&conn->snd_buf_cv);
    383289}
    384290
     
    952858        tcp_conn_trim_seg_to_wnd(conn, seg);
    953859
     860        fibril_mutex_lock(&conn->rcv_buf_lock);
     861
    954862        /* Determine how many bytes to copy */
    955863        text_size = tcp_segment_text_size(seg);
     
    963871        /* Signal to the receive function that new data has arrived */
    964872        fibril_condvar_broadcast(&conn->rcv_buf_cv);
     873        fibril_mutex_unlock(&conn->rcv_buf_lock);
    965874
    966875        log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
     
    1052961
    1053962                /* Add FIN to the receive buffer */
     963                fibril_mutex_lock(&conn->rcv_buf_lock);
    1054964                conn->rcv_buf_fin = true;
    1055965                fibril_condvar_broadcast(&conn->rcv_buf_cv);
     966                fibril_mutex_unlock(&conn->rcv_buf_lock);
    1056967
    1057968                tcp_segment_delete(seg);
     
    11621073        log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn);
    11631074
    1164         fibril_mutex_lock(&conn->lock);
    1165 
    11661075        if (conn->cstate == st_closed) {
    11671076                log_msg(LVL_DEBUG, "Connection already closed.");
    1168                 fibril_mutex_unlock(&conn->lock);
    1169                 tcp_conn_delref(conn);
    11701077                return;
    11711078        }
     
    11741081        tcp_conn_remove(conn);
    11751082        tcp_conn_state_set(conn, st_closed);
    1176 
    1177         fibril_mutex_unlock(&conn->lock);
    1178         tcp_conn_delref(conn);
    11791083}
    11801084
     
    11851089void tcp_conn_tw_timer_set(tcp_conn_t *conn)
    11861090{
    1187         tcp_conn_addref(conn);
    11881091        fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func,
    11891092            (void *)conn);
     
    11961099void tcp_conn_tw_timer_clear(tcp_conn_t *conn)
    11971100{
    1198         if (fibril_timer_clear(conn->tw_timer) == fts_active)
    1199                 tcp_conn_delref(conn);
     1101        fibril_timer_clear(conn->tw_timer);
    12001102}
    12011103
  • uspace/srv/net/tl/tcp/conn.h

    ra438de48 r58f6229  
    4040
    4141extern tcp_conn_t *tcp_conn_new(tcp_sock_t *, tcp_sock_t *);
    42 extern void tcp_conn_delete(tcp_conn_t *);
    4342extern void tcp_conn_add(tcp_conn_t *);
    4443extern void tcp_conn_remove(tcp_conn_t *);
     
    4645extern void tcp_conn_fin_sent(tcp_conn_t *);
    4746extern void tcp_conn_ack_of_fin_rcvd(tcp_conn_t *);
    48 extern tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *);
    49 extern void tcp_conn_addref(tcp_conn_t *);
    50 extern void tcp_conn_delref(tcp_conn_t *);
     47extern tcp_conn_t *tcp_conn_find(tcp_sockpair_t *);
    5148extern bool tcp_conn_got_syn(tcp_conn_t *);
    5249extern void tcp_conn_segment_arrived(tcp_conn_t *, tcp_segment_t *);
  • uspace/srv/net/tl/tcp/sock.c

    ra438de48 r58f6229  
    603603
    604604        socket = (tcp_sockdata_t *)sock_core->specific_data;
    605 
    606         if (socket->conn != NULL) {
    607                 trc = tcp_uc_close(socket->conn);
    608                 if (trc != TCP_EOK && trc != TCP_ENOTEXIST) {
    609                         async_answer_0(callid, EBADF);
    610                         return;
    611                 }
    612 
    613                 /* Drain incoming data. This should really be done in the background. */
    614                 do {
    615                         trc = tcp_uc_receive(socket->conn, buffer,
    616                             FRAGMENT_SIZE, &data_len, &xflags);
    617                 } while (trc == TCP_EOK);
    618 
    619                 tcp_uc_delete(socket->conn);
    620         }
     605        rc = tcp_uc_close(socket->conn);
     606        if (rc != EOK) {
     607                async_answer_0(callid, rc);
     608                return;
     609        }
     610
     611        /* Drain incoming data. This should really be done in the background. */
     612        do {
     613                trc = tcp_uc_receive(socket->conn, buffer, FRAGMENT_SIZE,
     614                    &data_len, &xflags);
     615        } while (trc == TCP_EOK);
    621616
    622617        rc = socket_destroy(net_sess, socket_id, &client->sockets, &gsock,
  • uspace/srv/net/tl/tcp/tcp_type.h

    ra438de48 r58f6229  
    162162        acpass_t ap;
    163163
    164         /** Protects access to connection structure */
    165         fibril_mutex_t lock;
    166         /** Reference count */
    167         atomic_t refcnt;
    168 
    169164        /** Connection state */
    170165        tcp_cstate_t cstate;
    171166        /** True if connection was reset */
    172167        bool reset;
    173         /** True if connection was deleted by user */
    174         bool deleted;
     168        /** Protects @c cstate */
     169        fibril_mutex_t cstate_lock;
    175170        /** Signalled when @c cstate changes */
    176171        fibril_condvar_t cstate_cv;
     
    196191        /** Receive buffer contains FIN */
    197192        bool rcv_buf_fin;
     193        /** Receive buffer lock */
     194        fibril_mutex_t rcv_buf_lock;
    198195        /** Receive buffer CV. Broadcast when new data is inserted */
    199196        fibril_condvar_t rcv_buf_cv;
     
    207204        /** Send buffer contains FIN */
    208205        bool snd_buf_fin;
    209         /** Send buffer CV. Broadcast when space is made available in buffer */
    210         fibril_condvar_t snd_buf_cv;
    211206
    212207        /** Send unacknowledged */
  • uspace/srv/net/tl/tcp/tqueue.c

    ra438de48 r58f6229  
    188188                /* We are sending out FIN */
    189189                ctrl = CTL_FIN;
     190                tcp_conn_fin_sent(conn);
    190191        } else {
    191192                ctrl = 0;
     
    205206        if (send_fin)
    206207                conn->snd_buf_fin = false;
    207 
    208         fibril_condvar_broadcast(&conn->snd_buf_cv);
    209 
    210         if (send_fin)
    211                 tcp_conn_fin_sent(conn);
    212208
    213209        tcp_tqueue_seg(conn, seg);
     
    317313        log_msg(LVL_DEBUG, "### %s: retransmit_timeout_func(%p)", conn->name, conn);
    318314
    319         fibril_mutex_lock(&conn->lock);
    320 
    321315        if (conn->cstate == st_closed) {
    322316                log_msg(LVL_DEBUG, "Connection already closed.");
    323                 fibril_mutex_unlock(&conn->lock);
    324                 tcp_conn_delref(conn);
    325317                return;
    326318        }
     
    329321        if (link == NULL) {
    330322                log_msg(LVL_DEBUG, "Nothing to retransmit");
    331                 fibril_mutex_unlock(&conn->lock);
    332                 tcp_conn_delref(conn);
    333323                return;
    334324        }
     
    339329        if (rt_seg == NULL) {
    340330                log_msg(LVL_ERROR, "Memory allocation failed.");
    341                 fibril_mutex_unlock(&conn->lock);
    342                 tcp_conn_delref(conn);
    343331                /* XXX Handle properly */
    344332                return;
     
    350338        /* Reset retransmission timer */
    351339        tcp_tqueue_timer_set(tqe->conn);
    352 
    353         fibril_mutex_unlock(&conn->lock);
    354         tcp_conn_delref(conn);
    355340}
    356341
     
    360345        log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_set()", conn->name);
    361346
    362         /* Clear first to make sure we update refcnt correctly */
    363         tcp_tqueue_timer_clear(conn);
    364 
    365         tcp_conn_addref(conn);
     347        (void) retransmit_timeout_func;
    366348        fibril_timer_set(conn->retransmit.timer, RETRANSMIT_TIMEOUT,
    367349            retransmit_timeout_func, (void *) conn);
     
    373355        log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_clear()", conn->name);
    374356
    375         if (fibril_timer_clear(conn->retransmit.timer) == fts_active)
    376                 tcp_conn_delref(conn);
     357        fibril_timer_clear(conn->retransmit.timer);
    377358}
    378359
  • uspace/srv/net/tl/tcp/ucall.c

    ra438de48 r58f6229  
    8383        /* Wait for connection to be established or reset */
    8484        log_msg(LVL_DEBUG, "tcp_uc_open: Wait for connection.");
    85         fibril_mutex_lock(&nconn->lock);
     85        fibril_mutex_lock(&nconn->cstate_lock);
    8686        while (nconn->cstate == st_listen ||
    8787            nconn->cstate == st_syn_sent ||
    8888            nconn->cstate == st_syn_received) {
    89                 fibril_condvar_wait(&nconn->cstate_cv, &nconn->lock);
     89                fibril_condvar_wait(&nconn->cstate_cv, &nconn->cstate_lock);
    9090        }
    9191
     
    9393                log_msg(LVL_DEBUG, "tcp_uc_open: Connection was reset.");
    9494                assert(nconn->cstate == st_closed);
    95                 fibril_mutex_unlock(&nconn->lock);
     95                fibril_mutex_unlock(&nconn->cstate_lock);
    9696                return TCP_ERESET;
    9797        }
    9898
    99         fibril_mutex_unlock(&nconn->lock);
     99        fibril_mutex_unlock(&nconn->cstate_lock);
    100100        log_msg(LVL_DEBUG, "tcp_uc_open: Connection was established.");
    101101
     
    113113        log_msg(LVL_DEBUG, "%s: tcp_uc_send()", conn->name);
    114114
    115         fibril_mutex_lock(&conn->lock);
    116 
    117         if (conn->cstate == st_closed) {
    118                 fibril_mutex_unlock(&conn->lock);
     115        if (conn->cstate == st_closed)
    119116                return TCP_ENOTEXIST;
    120         }
    121117
    122118        if (conn->cstate == st_listen) {
     
    125121        }
    126122
    127 
    128         if (conn->snd_buf_fin) {
    129                 fibril_mutex_unlock(&conn->lock);
     123        if (conn->snd_buf_fin)
    130124                return TCP_ECLOSING;
    131         }
    132125
    133126        while (size > 0) {
    134127                buf_free = conn->snd_buf_size - conn->snd_buf_used;
    135                 while (buf_free == 0 && !conn->reset) {
    136                         log_msg(LVL_DEBUG, "%s: buf_free == 0, waiting.",
    137                             conn->name);
    138                         fibril_condvar_wait(&conn->snd_buf_cv, &conn->lock);
    139                         buf_free = conn->snd_buf_size - conn->snd_buf_used;
    140                 }
    141 
    142                 if (conn->reset) {
    143                         fibril_mutex_unlock(&conn->lock);
     128                while (buf_free == 0 && !conn->reset)
     129                        tcp_tqueue_new_data(conn);
     130
     131                if (conn->reset)
    144132                        return TCP_ERESET;
    145                 }
    146133
    147134                xfer_size = min(size, buf_free);
     
    152139                conn->snd_buf_used += xfer_size;
    153140                size -= xfer_size;
    154 
    155                 tcp_tqueue_new_data(conn);
    156141        }
    157142
    158143        tcp_tqueue_new_data(conn);
    159         fibril_mutex_unlock(&conn->lock);
    160144
    161145        return TCP_EOK;
     
    170154        log_msg(LVL_DEBUG, "%s: tcp_uc_receive()", conn->name);
    171155
    172         fibril_mutex_lock(&conn->lock);
    173 
    174         if (conn->cstate == st_closed) {
    175                 fibril_mutex_unlock(&conn->lock);
     156        if (conn->cstate == st_closed)
    176157                return TCP_ENOTEXIST;
    177         }
     158
     159        fibril_mutex_lock(&conn->rcv_buf_lock);
    178160
    179161        /* Wait for data to become available */
    180162        while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin && !conn->reset) {
    181163                log_msg(LVL_DEBUG, "tcp_uc_receive() - wait for data");
    182                 fibril_condvar_wait(&conn->rcv_buf_cv, &conn->lock);
     164                fibril_condvar_wait(&conn->rcv_buf_cv, &conn->rcv_buf_lock);
    183165        }
    184166
    185167        if (conn->rcv_buf_used == 0) {
     168                fibril_mutex_unlock(&conn->rcv_buf_lock);
     169
    186170                *rcvd = 0;
    187171                *xflags = 0;
     
    189173                if (conn->rcv_buf_fin) {
    190174                        /* End of data, peer closed connection */
    191                         fibril_mutex_unlock(&conn->lock);
    192175                        return TCP_ECLOSING;
    193176                } else {
    194177                        /* Connection was reset */
    195178                        assert(conn->reset);
    196                         fibril_mutex_unlock(&conn->lock);
    197179                        return TCP_ERESET;
    198180                }
     
    210192        conn->rcv_wnd += xfer_size;
    211193
     194        fibril_mutex_unlock(&conn->rcv_buf_lock);
     195
    212196        /* TODO */
    213197        *xflags = 0;
     
    219203            conn->name, xfer_size);
    220204
    221         fibril_mutex_unlock(&conn->lock);
    222 
    223205        return TCP_EOK;
    224206}
     
    229211        log_msg(LVL_DEBUG, "%s: tcp_uc_close()", conn->name);
    230212
    231         fibril_mutex_lock(&conn->lock);
    232 
    233         if (conn->cstate == st_closed) {
    234                 fibril_mutex_unlock(&conn->lock);
     213        if (conn->cstate == st_closed)
    235214                return TCP_ENOTEXIST;
    236         }
    237 
    238         if (conn->snd_buf_fin) {
    239                 fibril_mutex_unlock(&conn->lock);
     215
     216        if (conn->snd_buf_fin)
    240217                return TCP_ECLOSING;
    241         }
    242218
    243219        conn->snd_buf_fin = true;
    244220        tcp_tqueue_new_data(conn);
    245221
    246         fibril_mutex_unlock(&conn->lock);
    247222        return TCP_EOK;
    248223}
     
    260235}
    261236
    262 /** Delete connection user call.
    263  *
    264  * (Not in spec.) Inform TCP that the user is done with this connection
    265  * and will not make any further calls/references to it. TCP can deallocate
    266  * the connection from now on.
    267  */
    268 void tcp_uc_delete(tcp_conn_t *conn)
    269 {
    270         log_msg(LVL_DEBUG, "tcp_uc_delete()");
    271         tcp_conn_delete(conn);
    272 }
    273237
    274238/*
     
    285249            sp->local.addr.ipv4, sp->local.port);
    286250
    287         conn = tcp_conn_find_ref(sp);
    288         if (conn == NULL) {
    289                 log_msg(LVL_WARN, "No connection found.");
     251        conn = tcp_conn_find(sp);
     252        if (conn != NULL && conn->cstate != st_closed) {
     253                if (conn->ident.foreign.addr.ipv4 == TCP_IPV4_ANY)
     254                        conn->ident.foreign.addr.ipv4 = sp->foreign.addr.ipv4;
     255                if (conn->ident.foreign.port == TCP_PORT_ANY)
     256                        conn->ident.foreign.port = sp->foreign.port;
     257                if (conn->ident.local.addr.ipv4 == TCP_IPV4_ANY)
     258                        conn->ident.local.addr.ipv4 = sp->local.addr.ipv4;
     259
     260                tcp_conn_segment_arrived(conn, seg);
     261        } else {
     262                if (conn == NULL)
     263                        log_msg(LVL_WARN, "No connection found.");
     264                else
     265                        log_msg(LVL_WARN, "Connection is closed.");
    290266                tcp_unexpected_segment(sp, seg);
    291                 return;
    292         }
    293 
    294         fibril_mutex_lock(&conn->lock);
    295 
    296         if (conn->cstate == st_closed) {
    297                 log_msg(LVL_WARN, "Connection is closed.");
    298                 tcp_unexpected_segment(sp, seg);
    299                 fibril_mutex_unlock(&conn->lock);
    300                 tcp_conn_delref(conn);
    301                 return;
    302         }
    303 
    304         if (conn->ident.foreign.addr.ipv4 == TCP_IPV4_ANY)
    305                 conn->ident.foreign.addr.ipv4 = sp->foreign.addr.ipv4;
    306         if (conn->ident.foreign.port == TCP_PORT_ANY)
    307                 conn->ident.foreign.port = sp->foreign.port;
    308         if (conn->ident.local.addr.ipv4 == TCP_IPV4_ANY)
    309                 conn->ident.local.addr.ipv4 = sp->local.addr.ipv4;
    310 
    311         tcp_conn_segment_arrived(conn, seg);
    312 
    313         fibril_mutex_unlock(&conn->lock);
    314         tcp_conn_delref(conn);
     267        }
    315268}
    316269
  • uspace/srv/net/tl/tcp/ucall.h

    ra438de48 r58f6229  
    4848extern void tcp_uc_abort(tcp_conn_t *);
    4949extern void tcp_uc_status(tcp_conn_t *, tcp_conn_status_t *);
    50 extern void tcp_uc_delete(tcp_conn_t *);
    5150
    5251/*
Note: See TracChangeset for help on using the changeset viewer.