Changes in uspace/srv/net/tl/tcp/conn.c [ae481e0:a52de0e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/conn.c
rae481e0 ra52de0e 56 56 57 57 LIST_INITIALIZE(conn_list); 58 FIBRIL_MUTEX_INITIALIZE(conn_list_lock);59 58 60 59 static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg); … … 62 61 static void tcp_conn_tw_timer_clear(tcp_conn_t *conn); 63 62 64 /** Create new connectionstructure.63 /** Create new segment structure. 65 64 * 66 65 * @param lsock Local socket (will be deeply copied) 67 66 * @param fsock Foreign socket (will be deeply copied) 68 * @return New connectionor NULL67 * @return New segment or NULL 69 68 */ 70 69 tcp_conn_t *tcp_conn_new(tcp_sock_t *lsock, tcp_sock_t *fsock) … … 82 81 goto error; 83 82 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 89 83 /* Allocate receive buffer */ 84 fibril_mutex_initialize(&conn->rcv_buf_lock); 90 85 fibril_condvar_initialize(&conn->rcv_buf_cv); 91 86 conn->rcv_buf_size = RCV_BUF_SIZE; … … 98 93 99 94 /** Allocate send buffer */ 100 fibril_condvar_initialize(&conn->snd_buf_cv);101 95 conn->snd_buf_size = SND_BUF_SIZE; 102 96 conn->snd_buf_used = 0; … … 119 113 120 114 /* Connection state change signalling */ 115 fibril_mutex_initialize(&conn->cstate_lock); 121 116 fibril_condvar_initialize(&conn->cstate_cv); 122 123 conn->cstate_cb = NULL;124 117 125 118 conn->cstate = st_listen; 126 119 conn->reset = false; 127 conn->deleted = false;128 120 conn->ap = ap_passive; 129 121 conn->fin_is_acked = false; … … 149 141 } 150 142 151 /** Destroy connection structure.152 *153 * Connection structure should be destroyed when the folowing condtitions154 * are met:155 * (1) user has deleted the connection156 * (2) the connection has entered closed state157 * (3) nobody is holding references to the connection158 *159 * This happens when @a conn->refcnt is zero as we count (1) and (2)160 * as special references.161 *162 * @param conn Connection163 */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 Connection183 */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 Connection195 */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 Connection210 */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 219 143 /** Enlist connection. 220 144 * … … 223 147 void tcp_conn_add(tcp_conn_t *conn) 224 148 { 225 tcp_conn_addref(conn);226 fibril_mutex_lock(&conn_list_lock);227 149 list_append(&conn->link, &conn_list); 228 fibril_mutex_unlock(&conn_list_lock);229 150 } 230 151 … … 235 156 void tcp_conn_remove(tcp_conn_t *conn) 236 157 { 237 fibril_mutex_lock(&conn_list_lock);238 158 list_remove(&conn->link); 239 fibril_mutex_unlock(&conn_list_lock);240 tcp_conn_delref(conn);241 159 } 242 160 243 161 static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate) 244 162 { 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); 250 164 conn->cstate = nstate; 251 165 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); 266 167 } 267 168 … … 350 251 * A connection is uniquely identified by a socket pair. Look up our 351 252 * connection map and return connection structure based on socket pair. 352 * The connection reference count is bumped by one.353 253 * 354 254 * @param sp Socket pair 355 255 * @return Connection structure or NULL if not found. 356 256 */ 357 tcp_conn_t *tcp_conn_find _ref(tcp_sockpair_t *sp)257 tcp_conn_t *tcp_conn_find(tcp_sockpair_t *sp) 358 258 { 359 259 log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp); 360 361 fibril_mutex_lock(&conn_list_lock);362 260 363 261 list_foreach(conn_list, link) { … … 368 266 csp->local.addr.ipv4, csp->local.port); 369 267 if (tcp_sockpair_match(sp, csp)) { 370 tcp_conn_addref(conn);371 fibril_mutex_unlock(&conn_list_lock);372 268 return conn; 373 269 } 374 270 } 375 271 376 fibril_mutex_unlock(&conn_list_lock);377 272 return NULL; 378 273 } … … 392 287 393 288 fibril_condvar_broadcast(&conn->rcv_buf_cv); 394 fibril_condvar_broadcast(&conn->snd_buf_cv);395 289 } 396 290 … … 503 397 conn->snd_una, seg->ack, conn->snd_nxt); 504 398 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); 511 401 return; 512 402 } … … 514 404 515 405 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; 528 412 } 529 413 … … 974 858 tcp_conn_trim_seg_to_wnd(conn, seg); 975 859 860 fibril_mutex_lock(&conn->rcv_buf_lock); 861 976 862 /* Determine how many bytes to copy */ 977 863 text_size = tcp_segment_text_size(seg); … … 985 871 /* Signal to the receive function that new data has arrived */ 986 872 fibril_condvar_broadcast(&conn->rcv_buf_cv); 873 fibril_mutex_unlock(&conn->rcv_buf_lock); 987 874 988 875 log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size); … … 1074 961 1075 962 /* Add FIN to the receive buffer */ 963 fibril_mutex_lock(&conn->rcv_buf_lock); 1076 964 conn->rcv_buf_fin = true; 1077 965 fibril_condvar_broadcast(&conn->rcv_buf_cv); 966 fibril_mutex_unlock(&conn->rcv_buf_lock); 1078 967 1079 968 tcp_segment_delete(seg); … … 1184 1073 log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn); 1185 1074 1186 fibril_mutex_lock(&conn->lock);1187 1188 1075 if (conn->cstate == st_closed) { 1189 1076 log_msg(LVL_DEBUG, "Connection already closed."); 1190 fibril_mutex_unlock(&conn->lock);1191 tcp_conn_delref(conn);1192 1077 return; 1193 1078 } … … 1196 1081 tcp_conn_remove(conn); 1197 1082 tcp_conn_state_set(conn, st_closed); 1198 1199 fibril_mutex_unlock(&conn->lock);1200 tcp_conn_delref(conn);1201 1083 } 1202 1084 … … 1207 1089 void tcp_conn_tw_timer_set(tcp_conn_t *conn) 1208 1090 { 1209 tcp_conn_addref(conn);1210 1091 fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func, 1211 1092 (void *)conn); … … 1218 1099 void tcp_conn_tw_timer_clear(tcp_conn_t *conn) 1219 1100 { 1220 if (fibril_timer_clear(conn->tw_timer) == fts_active) 1221 tcp_conn_delref(conn); 1101 fibril_timer_clear(conn->tw_timer); 1222 1102 } 1223 1103
Note:
See TracChangeset
for help on using the changeset viewer.