Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/tcp/conn.c

    r2f0dd2a ra52de0e  
    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
     
    491397                    conn->snd_una, seg->ack, conn->snd_nxt);
    492398                if (!seq_no_ack_acceptable(conn, seg->ack)) {
    493                         if ((seg->ctrl & CTL_RST) == 0) {
    494                                 log_msg(LVL_WARN, "ACK not acceptable, send RST");
    495                                 tcp_reply_rst(&conn->ident, seg);
    496                         } else {
    497                                 log_msg(LVL_WARN, "RST,ACK not acceptable, drop");
    498                         }
     399                        log_msg(LVL_WARN, "ACK not acceptable, send RST.");
     400                        tcp_reply_rst(&conn->ident, seg);
    499401                        return;
    500402                }
     
    502404
    503405        if ((seg->ctrl & CTL_RST) != 0) {
    504                 /* If we get here, we have either an acceptable ACK or no ACK */
    505                 if ((seg->ctrl & CTL_ACK) != 0) {
    506                         log_msg(LVL_DEBUG, "%s: Connection reset. -> Closed",
    507                             conn->name);
    508                         /* Reset connection */
    509                         tcp_conn_reset(conn);
    510                         return;
    511                 } else {
    512                         log_msg(LVL_DEBUG, "%s: RST without ACK, drop",
    513                             conn->name);
    514                         return;
    515                 }
     406                log_msg(LVL_DEBUG, "%s: Connection reset. -> Closed",
     407                    conn->name);
     408                /* Reset connection */
     409                tcp_conn_reset(conn);
     410                /* XXX delete connection */
     411                return;
    516412        }
    517413
     
    962858        tcp_conn_trim_seg_to_wnd(conn, seg);
    963859
     860        fibril_mutex_lock(&conn->rcv_buf_lock);
     861
    964862        /* Determine how many bytes to copy */
    965863        text_size = tcp_segment_text_size(seg);
     
    973871        /* Signal to the receive function that new data has arrived */
    974872        fibril_condvar_broadcast(&conn->rcv_buf_cv);
     873        fibril_mutex_unlock(&conn->rcv_buf_lock);
    975874
    976875        log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
     
    1062961
    1063962                /* Add FIN to the receive buffer */
     963                fibril_mutex_lock(&conn->rcv_buf_lock);
    1064964                conn->rcv_buf_fin = true;
    1065965                fibril_condvar_broadcast(&conn->rcv_buf_cv);
     966                fibril_mutex_unlock(&conn->rcv_buf_lock);
    1066967
    1067968                tcp_segment_delete(seg);
     
    11721073        log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn);
    11731074
    1174         fibril_mutex_lock(&conn->lock);
    1175 
    11761075        if (conn->cstate == st_closed) {
    11771076                log_msg(LVL_DEBUG, "Connection already closed.");
    1178                 fibril_mutex_unlock(&conn->lock);
    1179                 tcp_conn_delref(conn);
    11801077                return;
    11811078        }
     
    11841081        tcp_conn_remove(conn);
    11851082        tcp_conn_state_set(conn, st_closed);
    1186 
    1187         fibril_mutex_unlock(&conn->lock);
    1188         tcp_conn_delref(conn);
    11891083}
    11901084
     
    11951089void tcp_conn_tw_timer_set(tcp_conn_t *conn)
    11961090{
    1197         tcp_conn_addref(conn);
    11981091        fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func,
    11991092            (void *)conn);
     
    12061099void tcp_conn_tw_timer_clear(tcp_conn_t *conn)
    12071100{
    1208         if (fibril_timer_clear(conn->tw_timer) == fts_active)
    1209                 tcp_conn_delref(conn);
     1101        fibril_timer_clear(conn->tw_timer);
    12101102}
    12111103
Note: See TracChangeset for help on using the changeset viewer.