Changes in uspace/srv/net/tl/tcp/conn.c [2f0dd2a:a52de0e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/conn.c
r2f0dd2a 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 117 123 118 conn->cstate = st_listen; 124 119 conn->reset = false; 125 conn->deleted = false;126 120 conn->ap = ap_passive; 127 121 conn->fin_is_acked = false; … … 147 141 } 148 142 149 /** Destroy connection structure.150 *151 * Connection structure should be destroyed when the folowing condtitions152 * are met:153 * (1) user has deleted the connection154 * (2) the connection has entered closed state155 * (3) nobody is holding references to the connection156 *157 * This happens when @a conn->refcnt is zero as we count (1) and (2)158 * as special references.159 *160 * @param conn Connection161 */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 Connection181 */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 Connection193 */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 Connection208 */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 217 143 /** Enlist connection. 218 144 * … … 221 147 void tcp_conn_add(tcp_conn_t *conn) 222 148 { 223 tcp_conn_addref(conn);224 fibril_mutex_lock(&conn_list_lock);225 149 list_append(&conn->link, &conn_list); 226 fibril_mutex_unlock(&conn_list_lock);227 150 } 228 151 … … 233 156 void tcp_conn_remove(tcp_conn_t *conn) 234 157 { 235 fibril_mutex_lock(&conn_list_lock);236 158 list_remove(&conn->link); 237 fibril_mutex_unlock(&conn_list_lock);238 tcp_conn_delref(conn);239 159 } 240 160 241 161 static void tcp_conn_state_set(tcp_conn_t *conn, tcp_cstate_t nstate) 242 162 { 243 tcp_cstate_t old_state; 244 245 old_state = conn->cstate; 163 fibril_mutex_lock(&conn->cstate_lock); 246 164 conn->cstate = nstate; 247 165 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); 254 167 } 255 168 … … 338 251 * A connection is uniquely identified by a socket pair. Look up our 339 252 * connection map and return connection structure based on socket pair. 340 * The connection reference count is bumped by one.341 253 * 342 254 * @param sp Socket pair 343 255 * @return Connection structure or NULL if not found. 344 256 */ 345 tcp_conn_t *tcp_conn_find _ref(tcp_sockpair_t *sp)257 tcp_conn_t *tcp_conn_find(tcp_sockpair_t *sp) 346 258 { 347 259 log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp); 348 349 fibril_mutex_lock(&conn_list_lock);350 260 351 261 list_foreach(conn_list, link) { … … 356 266 csp->local.addr.ipv4, csp->local.port); 357 267 if (tcp_sockpair_match(sp, csp)) { 358 tcp_conn_addref(conn);359 fibril_mutex_unlock(&conn_list_lock);360 268 return conn; 361 269 } 362 270 } 363 271 364 fibril_mutex_unlock(&conn_list_lock);365 272 return NULL; 366 273 } … … 380 287 381 288 fibril_condvar_broadcast(&conn->rcv_buf_cv); 382 fibril_condvar_broadcast(&conn->snd_buf_cv);383 289 } 384 290 … … 491 397 conn->snd_una, seg->ack, conn->snd_nxt); 492 398 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); 499 401 return; 500 402 } … … 502 404 503 405 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; 516 412 } 517 413 … … 962 858 tcp_conn_trim_seg_to_wnd(conn, seg); 963 859 860 fibril_mutex_lock(&conn->rcv_buf_lock); 861 964 862 /* Determine how many bytes to copy */ 965 863 text_size = tcp_segment_text_size(seg); … … 973 871 /* Signal to the receive function that new data has arrived */ 974 872 fibril_condvar_broadcast(&conn->rcv_buf_cv); 873 fibril_mutex_unlock(&conn->rcv_buf_lock); 975 874 976 875 log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size); … … 1062 961 1063 962 /* Add FIN to the receive buffer */ 963 fibril_mutex_lock(&conn->rcv_buf_lock); 1064 964 conn->rcv_buf_fin = true; 1065 965 fibril_condvar_broadcast(&conn->rcv_buf_cv); 966 fibril_mutex_unlock(&conn->rcv_buf_lock); 1066 967 1067 968 tcp_segment_delete(seg); … … 1172 1073 log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn); 1173 1074 1174 fibril_mutex_lock(&conn->lock);1175 1176 1075 if (conn->cstate == st_closed) { 1177 1076 log_msg(LVL_DEBUG, "Connection already closed."); 1178 fibril_mutex_unlock(&conn->lock);1179 tcp_conn_delref(conn);1180 1077 return; 1181 1078 } … … 1184 1081 tcp_conn_remove(conn); 1185 1082 tcp_conn_state_set(conn, st_closed); 1186 1187 fibril_mutex_unlock(&conn->lock);1188 tcp_conn_delref(conn);1189 1083 } 1190 1084 … … 1195 1089 void tcp_conn_tw_timer_set(tcp_conn_t *conn) 1196 1090 { 1197 tcp_conn_addref(conn);1198 1091 fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func, 1199 1092 (void *)conn); … … 1206 1099 void tcp_conn_tw_timer_clear(tcp_conn_t *conn) 1207 1100 { 1208 if (fibril_timer_clear(conn->tw_timer) == fts_active) 1209 tcp_conn_delref(conn); 1101 fibril_timer_clear(conn->tw_timer); 1210 1102 } 1211 1103
Note:
See TracChangeset
for help on using the changeset viewer.