Changes in uspace/srv/net/tcp/conn.c [dc12262:3e2291a9] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tcp/conn.c
rdc12262 r3e2291a9 44 44 #include <stdlib.h> 45 45 #include "conn.h" 46 #include "inet.h" 46 47 #include "iqueue.h" 48 #include "pdu.h" 49 #include "rqueue.h" 47 50 #include "segment.h" 48 51 #include "seq_no.h" … … 57 60 #define TIME_WAIT_TIMEOUT (2*MAX_SEGMENT_LIFETIME) 58 61 62 /** List of all allocated connections */ 59 63 static LIST_INITIALIZE(conn_list); 60 64 /** Taken after tcp_conn_t lock */ 61 65 static FIBRIL_MUTEX_INITIALIZE(conn_list_lock); 66 /** Connection association map */ 62 67 static amap_t *amap; 63 64 static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg); 65 static void tcp_conn_tw_timer_set(tcp_conn_t *conn); 66 static void tcp_conn_tw_timer_clear(tcp_conn_t *conn); 68 /** Taken after tcp_conn_t lock */ 69 static FIBRIL_MUTEX_INITIALIZE(amap_lock); 70 71 /** Internal loopback configuration */ 72 tcp_lb_t tcp_conn_lb = tcp_lb_none; 73 74 static void tcp_conn_seg_process(tcp_conn_t *, tcp_segment_t *); 75 static void tcp_conn_tw_timer_set(tcp_conn_t *); 76 static void tcp_conn_tw_timer_clear(tcp_conn_t *); 77 static void tcp_transmit_segment(inet_ep2_t *, tcp_segment_t *); 78 static void tcp_conn_trim_seg_to_wnd(tcp_conn_t *, tcp_segment_t *); 79 static void tcp_reply_rst(inet_ep2_t *, tcp_segment_t *); 80 81 static tcp_tqueue_cb_t tcp_conn_tqueue_cb = { 82 .transmit_seg = tcp_transmit_segment 83 }; 67 84 68 85 /** Initialize connections. */ … … 78 95 79 96 return EOK; 97 } 98 99 /** Finalize connections. */ 100 void tcp_conns_fini(void) 101 { 102 assert(list_empty(&conn_list)); 103 104 amap_destroy(amap); 105 amap = NULL; 80 106 } 81 107 … … 130 156 131 157 /* Initialize retransmission queue */ 132 if (tcp_tqueue_init(&conn->retransmit, conn) != EOK) 158 if (tcp_tqueue_init(&conn->retransmit, conn, &tcp_conn_tqueue_cb) 159 != EOK) { 133 160 goto error; 161 } 134 162 135 163 tqueue_inited = true; … … 147 175 if (epp != NULL) 148 176 conn->ident = *epp; 177 178 fibril_mutex_lock(&conn_list_lock); 179 list_append(&conn->link, &conn_list); 180 fibril_mutex_unlock(&conn_list_lock); 149 181 150 182 return conn; … … 181 213 { 182 214 log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_free(%p)", conn->name, conn); 215 216 assert(conn->mapped == false); 183 217 tcp_tqueue_fini(&conn->retransmit); 218 219 fibril_mutex_lock(&conn_list_lock); 220 list_remove(&conn->link); 221 fibril_mutex_unlock(&conn_list_lock); 184 222 185 223 if (conn->rcv_buf != NULL) … … 271 309 272 310 tcp_conn_addref(conn); 273 fibril_mutex_lock(& conn_list_lock);311 fibril_mutex_lock(&amap_lock); 274 312 275 313 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_add: conn=%p", conn); … … 278 316 if (rc != EOK) { 279 317 tcp_conn_delref(conn); 280 fibril_mutex_unlock(& conn_list_lock);318 fibril_mutex_unlock(&amap_lock); 281 319 return rc; 282 320 } 283 321 284 322 conn->ident = aepp; 285 list_append(&conn->link, &conn_list);286 fibril_mutex_unlock(& conn_list_lock);323 conn->mapped = true; 324 fibril_mutex_unlock(&amap_lock); 287 325 288 326 return EOK; … … 293 331 * Remove connection from the connection map. 294 332 */ 295 void tcp_conn_remove(tcp_conn_t *conn) 296 { 297 fibril_mutex_lock(&conn_list_lock); 333 static void tcp_conn_remove(tcp_conn_t *conn) 334 { 335 if (!conn->mapped) 336 return; 337 338 fibril_mutex_lock(&amap_lock); 298 339 amap_remove(amap, &conn->ident); 299 list_remove(&conn->link);300 fibril_mutex_unlock(& conn_list_lock);340 conn->mapped = false; 341 fibril_mutex_unlock(&amap_lock); 301 342 tcp_conn_delref(conn); 302 343 } … … 335 376 void tcp_conn_sync(tcp_conn_t *conn) 336 377 { 378 assert(fibril_mutex_is_locked(&conn->lock)); 379 337 380 /* XXX select ISS */ 338 381 conn->iss = 1; … … 388 431 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_find_ref(%p)", epp); 389 432 390 fibril_mutex_lock(& conn_list_lock);433 fibril_mutex_lock(&amap_lock); 391 434 392 435 rc = amap_find_match(amap, epp, &arg); 393 436 if (rc != EOK) { 394 437 assert(rc == ENOENT); 395 fibril_mutex_unlock(& conn_list_lock);438 fibril_mutex_unlock(&amap_lock); 396 439 return NULL; 397 440 } … … 400 443 tcp_conn_addref(conn); 401 444 402 fibril_mutex_unlock(& conn_list_lock);445 fibril_mutex_unlock(&amap_lock); 403 446 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_find_ref: got conn=%p", 404 447 conn); … … 412 455 void tcp_conn_reset(tcp_conn_t *conn) 413 456 { 457 assert(fibril_mutex_is_locked(&conn->lock)); 458 414 459 log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_reset()", conn->name); 460 461 if (conn->cstate == st_closed) 462 return; 463 415 464 conn->reset = true; 416 465 tcp_conn_state_set(conn, st_closed); … … 865 914 return cp_done; 866 915 867 /* TODO */ 916 if (conn->fin_is_acked) { 917 log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN acked -> Time-Wait", 918 conn->name); 919 tcp_conn_state_set(conn, st_time_wait); 920 } 921 868 922 return cp_continue; 869 923 } … … 1062 1116 log_msg(LOG_DEFAULT, LVL_DEBUG, " - FIN found in segment."); 1063 1117 1118 conn->rcv_nxt++; 1119 conn->rcv_wnd--; 1120 1064 1121 /* Send ACK */ 1065 1122 tcp_tqueue_ctrl_seg(conn, CTL_ACK); 1066 1067 conn->rcv_nxt++;1068 conn->rcv_wnd--;1069 1123 1070 1124 /* Change connection state */ … … 1211 1265 1212 1266 /* Need to remove and re-insert connection with new identity */ 1213 fibril_mutex_lock(& conn_list_lock);1267 fibril_mutex_lock(&amap_lock); 1214 1268 1215 1269 if (inet_addr_is_any(&conn->ident.remote.addr)) … … 1227 1281 assert(rc == ENOMEM); 1228 1282 log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory."); 1229 fibril_mutex_unlock(& conn_list_lock);1283 fibril_mutex_unlock(&amap_lock); 1230 1284 tcp_conn_unlock(conn); 1231 1285 return; … … 1233 1287 1234 1288 amap_remove(amap, &oldepp); 1235 fibril_mutex_unlock(& conn_list_lock);1289 fibril_mutex_unlock(&amap_lock); 1236 1290 1237 1291 conn->name = (char *) "a"; … … 1322 1376 * @param seg Segment 1323 1377 */ 1324 void tcp_conn_trim_seg_to_wnd(tcp_conn_t *conn, tcp_segment_t *seg)1378 static void tcp_conn_trim_seg_to_wnd(tcp_conn_t *conn, tcp_segment_t *seg) 1325 1379 { 1326 1380 uint32_t left, right; … … 1346 1400 } 1347 1401 1402 /** Transmit segment over network. 1403 * 1404 * @param epp Endpoint pair with source and destination information 1405 * @param seg Segment (ownership retained by caller) 1406 */ 1407 static void tcp_transmit_segment(inet_ep2_t *epp, tcp_segment_t *seg) 1408 { 1409 tcp_pdu_t *pdu; 1410 tcp_segment_t *dseg; 1411 inet_ep2_t rident; 1412 1413 log_msg(LOG_DEFAULT, LVL_DEBUG, 1414 "tcp_transmit_segment(l:(%u),f:(%u), %p)", 1415 epp->local.port, epp->remote.port, seg); 1416 1417 log_msg(LOG_DEFAULT, LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32, 1418 seg->seq, seg->wnd); 1419 1420 tcp_segment_dump(seg); 1421 1422 if (tcp_conn_lb == tcp_lb_segment) { 1423 /* Loop back segment */ 1424 // tcp_ncsim_bounce_seg(sp, seg); 1425 1426 /* Reverse the identification */ 1427 tcp_ep2_flipped(epp, &rident); 1428 1429 /* Insert segment back into rqueue */ 1430 dseg = tcp_segment_dup(seg); 1431 tcp_rqueue_insert_seg(&rident, dseg); 1432 return; 1433 } 1434 1435 if (tcp_pdu_encode(epp, seg, &pdu) != EOK) { 1436 log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped."); 1437 return; 1438 } 1439 1440 if (tcp_conn_lb == tcp_lb_pdu) { 1441 /* Loop back PDU */ 1442 if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) { 1443 log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped."); 1444 tcp_pdu_delete(pdu); 1445 return; 1446 } 1447 1448 tcp_pdu_delete(pdu); 1449 1450 /* Insert decoded segment into rqueue */ 1451 tcp_rqueue_insert_seg(&rident, dseg); 1452 return; 1453 } 1454 1455 tcp_transmit_pdu(pdu); 1456 tcp_pdu_delete(pdu); 1457 } 1458 1348 1459 /** Compute flipped endpoint pair for response. 1349 1460 * … … 1364 1475 * @param seg Incoming segment 1365 1476 */ 1366 void tcp_reply_rst(inet_ep2_t *epp, tcp_segment_t *seg)1477 static void tcp_reply_rst(inet_ep2_t *epp, tcp_segment_t *seg) 1367 1478 { 1368 1479 tcp_segment_t *rseg;
Note:
See TracChangeset
for help on using the changeset viewer.