Changeset 7943c43 in mainline for uspace/srv/net/tl/tcp/conn.c
- Timestamp:
- 2012-01-16T22:45:38Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 32817cc, 3fe58d3c
- Parents:
- 9117ef9b (diff), 3ea725e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/conn.c
r9117ef9b r7943c43 56 56 57 57 LIST_INITIALIZE(conn_list); 58 FIBRIL_MUTEX_INITIALIZE(conn_list_lock); 58 59 59 60 static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg); … … 61 62 static void tcp_conn_tw_timer_clear(tcp_conn_t *conn); 62 63 63 /** Create new segmentstructure.64 /** Create new connection structure. 64 65 * 65 66 * @param lsock Local socket (will be deeply copied) 66 67 * @param fsock Foreign socket (will be deeply copied) 67 * @return New segmentor NULL68 * @return New connection or NULL 68 69 */ 69 70 tcp_conn_t *tcp_conn_new(tcp_sock_t *lsock, tcp_sock_t *fsock) … … 81 82 goto error; 82 83 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 83 89 /* Allocate receive buffer */ 84 fibril_mutex_initialize(&conn->rcv_buf_lock);85 90 fibril_condvar_initialize(&conn->rcv_buf_cv); 86 91 conn->rcv_buf_size = RCV_BUF_SIZE; … … 93 98 94 99 /** Allocate send buffer */ 100 fibril_condvar_initialize(&conn->snd_buf_cv); 95 101 conn->snd_buf_size = SND_BUF_SIZE; 96 102 conn->snd_buf_used = 0; … … 113 119 114 120 /* Connection state change signalling */ 115 fibril_mutex_initialize(&conn->cstate_lock);116 121 fibril_condvar_initialize(&conn->cstate_cv); 122 123 conn->cstate_cb = NULL; 117 124 118 125 conn->cstate = st_listen; 119 126 conn->reset = false; 127 conn->deleted = false; 120 128 conn->ap = ap_passive; 121 129 conn->fin_is_acked = false; … … 141 149 } 142 150 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 143 219 /** Enlist connection. 144 220 * … … 147 223 void tcp_conn_add(tcp_conn_t *conn) 148 224 { 225 tcp_conn_addref(conn); 226 fibril_mutex_lock(&conn_list_lock); 149 227 list_append(&conn->link, &conn_list); 228 fibril_mutex_unlock(&conn_list_lock); 150 229 } 151 230 … … 156 235 void tcp_conn_remove(tcp_conn_t *conn) 157 236 { 237 fibril_mutex_lock(&conn_list_lock); 158 238 list_remove(&conn->link); 239 fibril_mutex_unlock(&conn_list_lock); 240 tcp_conn_delref(conn); 159 241 } 160 242 161 243 static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate) 162 244 { 163 fibril_mutex_lock(&conn->cstate_lock); 245 tcp_cstate_t old_state; 246 247 log_msg(LVL_DEBUG, "tcp_conn_state_set(%p)", conn); 248 249 old_state = conn->cstate; 164 250 conn->cstate = nstate; 165 251 fibril_condvar_broadcast(&conn->cstate_cv); 166 fibril_mutex_unlock(&conn->cstate_lock); 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 } 167 266 } 168 267 … … 251 350 * A connection is uniquely identified by a socket pair. Look up our 252 351 * connection map and return connection structure based on socket pair. 352 * The connection reference count is bumped by one. 253 353 * 254 354 * @param sp Socket pair 255 355 * @return Connection structure or NULL if not found. 256 356 */ 257 tcp_conn_t *tcp_conn_find (tcp_sockpair_t *sp)357 tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp) 258 358 { 259 359 log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp); 360 361 fibril_mutex_lock(&conn_list_lock); 260 362 261 363 list_foreach(conn_list, link) { … … 266 368 csp->local.addr.ipv4, csp->local.port); 267 369 if (tcp_sockpair_match(sp, csp)) { 370 tcp_conn_addref(conn); 371 fibril_mutex_unlock(&conn_list_lock); 268 372 return conn; 269 373 } 270 374 } 271 375 376 fibril_mutex_unlock(&conn_list_lock); 272 377 return NULL; 273 378 } … … 287 392 288 393 fibril_condvar_broadcast(&conn->rcv_buf_cv); 394 fibril_condvar_broadcast(&conn->snd_buf_cv); 289 395 } 290 396 … … 397 503 conn->snd_una, seg->ack, conn->snd_nxt); 398 504 if (!seq_no_ack_acceptable(conn, seg->ack)) { 399 log_msg(LVL_WARN, "ACK not acceptable, send RST."); 400 tcp_reply_rst(&conn->ident, seg); 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 } 401 511 return; 402 512 } … … 404 514 405 515 if ((seg->ctrl & CTL_RST) != 0) { 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; 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 } 412 528 } 413 529 … … 858 974 tcp_conn_trim_seg_to_wnd(conn, seg); 859 975 860 fibril_mutex_lock(&conn->rcv_buf_lock);861 862 976 /* Determine how many bytes to copy */ 863 977 text_size = tcp_segment_text_size(seg); … … 871 985 /* Signal to the receive function that new data has arrived */ 872 986 fibril_condvar_broadcast(&conn->rcv_buf_cv); 873 fibril_mutex_unlock(&conn->rcv_buf_lock);874 987 875 988 log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size); … … 961 1074 962 1075 /* Add FIN to the receive buffer */ 963 fibril_mutex_lock(&conn->rcv_buf_lock);964 1076 conn->rcv_buf_fin = true; 965 1077 fibril_condvar_broadcast(&conn->rcv_buf_cv); 966 fibril_mutex_unlock(&conn->rcv_buf_lock);967 1078 968 1079 tcp_segment_delete(seg); … … 1073 1184 log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn); 1074 1185 1186 fibril_mutex_lock(&conn->lock); 1187 1075 1188 if (conn->cstate == st_closed) { 1076 1189 log_msg(LVL_DEBUG, "Connection already closed."); 1190 fibril_mutex_unlock(&conn->lock); 1191 tcp_conn_delref(conn); 1077 1192 return; 1078 1193 } … … 1081 1196 tcp_conn_remove(conn); 1082 1197 tcp_conn_state_set(conn, st_closed); 1198 1199 fibril_mutex_unlock(&conn->lock); 1200 tcp_conn_delref(conn); 1083 1201 } 1084 1202 … … 1089 1207 void tcp_conn_tw_timer_set(tcp_conn_t *conn) 1090 1208 { 1209 tcp_conn_addref(conn); 1091 1210 fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func, 1092 1211 (void *)conn); … … 1099 1218 void tcp_conn_tw_timer_clear(tcp_conn_t *conn) 1100 1219 { 1101 fibril_timer_clear(conn->tw_timer); 1220 if (fibril_timer_clear(conn->tw_timer) == fts_active) 1221 tcp_conn_delref(conn); 1102 1222 } 1103 1223
Note:
See TracChangeset
for help on using the changeset viewer.