Ignore:
File:
1 edited

Legend:

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

    rae481e0 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);
    122 
    123         conn->cstate_cb = NULL;
    124117
    125118        conn->cstate = st_listen;
    126119        conn->reset = false;
    127         conn->deleted = false;
    128120        conn->ap = ap_passive;
    129121        conn->fin_is_acked = false;
     
    149141}
    150142
    151 /** Destroy connection structure.
    152  *
    153  * Connection structure should be destroyed when the folowing condtitions
    154  * are met:
    155  * (1) user has deleted the connection
    156  * (2) the connection has entered closed state
    157  * (3) nobody is holding references to the connection
    158  *
    159  * This happens when @a conn->refcnt is zero as we count (1) and (2)
    160  * as special references.
    161  *
    162  * @param conn          Connection
    163  */
    164 static void tcp_conn_free(tcp_conn_t *conn)
    165 {
    166         log_msg(LVL_DEBUG, "%s: tcp_conn_free(%p)", conn->name, conn);
    167         tcp_tqueue_fini(&conn->retransmit);
    168 
    169         if (conn->rcv_buf != NULL)
    170                 free(conn->rcv_buf);
    171         if (conn->snd_buf != NULL)
    172                 free(conn->snd_buf);
    173         if (conn->tw_timer != NULL)
    174                 fibril_timer_destroy(conn->tw_timer);
    175         free(conn);
    176 }
    177 
    178 /** Add reference to connection.
    179  *
    180  * Increase connection reference count by one.
    181  *
    182  * @param conn          Connection
    183  */
    184 void tcp_conn_addref(tcp_conn_t *conn)
    185 {
    186         log_msg(LVL_DEBUG, "%s: tcp_conn_addref(%p)", conn->name, conn);
    187         atomic_inc(&conn->refcnt);
    188 }
    189 
    190 /** Remove reference from connection.
    191  *
    192  * Decrease connection reference count by one.
    193  *
    194  * @param conn          Connection
    195  */
    196 void tcp_conn_delref(tcp_conn_t *conn)
    197 {
    198         log_msg(LVL_DEBUG, "%s: tcp_conn_delref(%p)", conn->name, conn);
    199 
    200         if (atomic_predec(&conn->refcnt) == 0)
    201                 tcp_conn_free(conn);
    202 }
    203 
    204 /** Delete connection.
    205  *
    206  * The caller promises not make no further references to @a conn.
    207  * TCP will free @a conn eventually.
    208  *
    209  * @param conn          Connection
    210  */
    211 void tcp_conn_delete(tcp_conn_t *conn)
    212 {
    213         log_msg(LVL_DEBUG, "%s: tcp_conn_delete(%p)", conn->name, conn);
    214 
    215         assert(conn->deleted == false);
    216         tcp_conn_delref(conn);
    217 }
    218 
    219143/** Enlist connection.
    220144 *
     
    223147void tcp_conn_add(tcp_conn_t *conn)
    224148{
    225         tcp_conn_addref(conn);
    226         fibril_mutex_lock(&conn_list_lock);
    227149        list_append(&conn->link, &conn_list);
    228         fibril_mutex_unlock(&conn_list_lock);
    229150}
    230151
     
    235156void tcp_conn_remove(tcp_conn_t *conn)
    236157{
    237         fibril_mutex_lock(&conn_list_lock);
    238158        list_remove(&conn->link);
    239         fibril_mutex_unlock(&conn_list_lock);
    240         tcp_conn_delref(conn);
    241159}
    242160
    243161static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate)
    244162{
    245         tcp_cstate_t old_state;
    246 
    247         log_msg(LVL_DEBUG, "tcp_conn_state_set(%p)", conn);
    248 
    249         old_state = conn->cstate;
     163        fibril_mutex_lock(&conn->cstate_lock);
    250164        conn->cstate = nstate;
    251165        fibril_condvar_broadcast(&conn->cstate_cv);
    252 
    253         /* Run user callback function */
    254         if (conn->cstate_cb != NULL) {
    255                 log_msg(LVL_DEBUG, "tcp_conn_state_set() - run user CB");
    256                 conn->cstate_cb(conn, conn->cstate_cb_arg);
    257         } else {
    258                 log_msg(LVL_DEBUG, "tcp_conn_state_set() - no user CB");
    259         }
    260 
    261         assert(old_state != st_closed);
    262         if (nstate == st_closed) {
    263                 /* Drop one reference for now being in closed state */
    264                 tcp_conn_delref(conn);
    265         }
     166        fibril_mutex_unlock(&conn->cstate_lock);
    266167}
    267168
     
    350251 * A connection is uniquely identified by a socket pair. Look up our
    351252 * connection map and return connection structure based on socket pair.
    352  * The connection reference count is bumped by one.
    353253 *
    354254 * @param sp    Socket pair
    355255 * @return      Connection structure or NULL if not found.
    356256 */
    357 tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp)
     257tcp_conn_t *tcp_conn_find(tcp_sockpair_t *sp)
    358258{
    359259        log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp);
    360 
    361         fibril_mutex_lock(&conn_list_lock);
    362260
    363261        list_foreach(conn_list, link) {
     
    368266                    csp->local.addr.ipv4, csp->local.port);
    369267                if (tcp_sockpair_match(sp, csp)) {
    370                         tcp_conn_addref(conn);
    371                         fibril_mutex_unlock(&conn_list_lock);
    372268                        return conn;
    373269                }
    374270        }
    375271
    376         fibril_mutex_unlock(&conn_list_lock);
    377272        return NULL;
    378273}
     
    392287
    393288        fibril_condvar_broadcast(&conn->rcv_buf_cv);
    394         fibril_condvar_broadcast(&conn->snd_buf_cv);
    395289}
    396290
     
    503397                    conn->snd_una, seg->ack, conn->snd_nxt);
    504398                if (!seq_no_ack_acceptable(conn, seg->ack)) {
    505                         if ((seg->ctrl & CTL_RST) == 0) {
    506                                 log_msg(LVL_WARN, "ACK not acceptable, send RST");
    507                                 tcp_reply_rst(&conn->ident, seg);
    508                         } else {
    509                                 log_msg(LVL_WARN, "RST,ACK not acceptable, drop");
    510                         }
     399                        log_msg(LVL_WARN, "ACK not acceptable, send RST.");
     400                        tcp_reply_rst(&conn->ident, seg);
    511401                        return;
    512402                }
     
    514404
    515405        if ((seg->ctrl & CTL_RST) != 0) {
    516                 /* If we get here, we have either an acceptable ACK or no ACK */
    517                 if ((seg->ctrl & CTL_ACK) != 0) {
    518                         log_msg(LVL_DEBUG, "%s: Connection reset. -> Closed",
    519                             conn->name);
    520                         /* Reset connection */
    521                         tcp_conn_reset(conn);
    522                         return;
    523                 } else {
    524                         log_msg(LVL_DEBUG, "%s: RST without ACK, drop",
    525                             conn->name);
    526                         return;
    527                 }
     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;
    528412        }
    529413
     
    974858        tcp_conn_trim_seg_to_wnd(conn, seg);
    975859
     860        fibril_mutex_lock(&conn->rcv_buf_lock);
     861
    976862        /* Determine how many bytes to copy */
    977863        text_size = tcp_segment_text_size(seg);
     
    985871        /* Signal to the receive function that new data has arrived */
    986872        fibril_condvar_broadcast(&conn->rcv_buf_cv);
     873        fibril_mutex_unlock(&conn->rcv_buf_lock);
    987874
    988875        log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
     
    1074961
    1075962                /* Add FIN to the receive buffer */
     963                fibril_mutex_lock(&conn->rcv_buf_lock);
    1076964                conn->rcv_buf_fin = true;
    1077965                fibril_condvar_broadcast(&conn->rcv_buf_cv);
     966                fibril_mutex_unlock(&conn->rcv_buf_lock);
    1078967
    1079968                tcp_segment_delete(seg);
     
    11841073        log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn);
    11851074
    1186         fibril_mutex_lock(&conn->lock);
    1187 
    11881075        if (conn->cstate == st_closed) {
    11891076                log_msg(LVL_DEBUG, "Connection already closed.");
    1190                 fibril_mutex_unlock(&conn->lock);
    1191                 tcp_conn_delref(conn);
    11921077                return;
    11931078        }
     
    11961081        tcp_conn_remove(conn);
    11971082        tcp_conn_state_set(conn, st_closed);
    1198 
    1199         fibril_mutex_unlock(&conn->lock);
    1200         tcp_conn_delref(conn);
    12011083}
    12021084
     
    12071089void tcp_conn_tw_timer_set(tcp_conn_t *conn)
    12081090{
    1209         tcp_conn_addref(conn);
    12101091        fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func,
    12111092            (void *)conn);
     
    12181099void tcp_conn_tw_timer_clear(tcp_conn_t *conn)
    12191100{
    1220         if (fibril_timer_clear(conn->tw_timer) == fts_active)
    1221                 tcp_conn_delref(conn);
     1101        fibril_timer_clear(conn->tw_timer);
    12221102}
    12231103
Note: See TracChangeset for help on using the changeset viewer.