Changeset 7cf7ded in mainline
- Timestamp:
- 2011-11-15T23:50:57Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4f3f6285
- Parents:
- 8218b6b
- Location:
- uspace
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
r8218b6b r7cf7ded 474 474 timer->delay); 475 475 if (rc == ETIMEOUT) { 476 timer->state = fts_fired; 477 fibril_mutex_unlock(&timer->lock); 476 478 timer->fun(timer->arg); 477 timer->state = fts_fired;479 fibril_mutex_lock(&timer->lock); 478 480 } 479 481 } -
uspace/srv/net/tl/tcp/conn.c
r8218b6b r7cf7ded 69 69 { 70 70 tcp_conn_t *conn = NULL; 71 bool tqueue_inited = false; 71 72 72 73 /* Allocate connection structure */ … … 105 106 106 107 /* Initialize retransmission queue */ 107 tcp_tqueue_init(&conn->retransmit, conn); 108 if (tcp_tqueue_init(&conn->retransmit, conn) != EOK) 109 goto error; 110 111 tqueue_inited = true; 108 112 109 113 conn->cstate = st_listen; … … 116 120 117 121 error: 122 if (tqueue_inited) 123 tcp_tqueue_fini(&conn->retransmit); 118 124 if (conn != NULL && conn->rcv_buf != NULL) 119 125 free(conn->rcv_buf); … … 180 186 break; 181 187 default: 188 log_msg(LVL_ERROR, "Connection state %d", conn->cstate); 182 189 assert(false); 183 190 } … … 264 271 return true; 265 272 case st_closed: 273 log_msg(LVL_WARN, "state=%d", (int) conn->cstate); 266 274 assert(false); 267 275 } … … 347 355 348 356 if ((seg->ctrl & CTL_RST) != 0) { 349 log_msg(LVL_DEBUG, "Connection reset. ");357 log_msg(LVL_DEBUG, "Connection reset. -> Closed"); 350 358 /* XXX Signal user error */ 351 359 conn->cstate = st_closed; … … 413 421 log_msg(LVL_DEBUG, "tcp_conn_sa_seq(%p, %p)", conn, seg); 414 422 415 /* XXX Discard old duplicates */ 423 /* Discard unacceptable segments ("old duplicates") */ 424 if (!seq_no_segment_acceptable(conn, seg)) { 425 log_msg(LVL_DEBUG, "Replying ACK to unacceptable segment."); 426 tcp_tqueue_ctrl_seg(conn, CTL_ACK); 427 tcp_segment_delete(seg); 428 return; 429 } 416 430 417 431 /* Queue for processing */ … … 463 477 static cproc_t tcp_conn_seg_proc_syn(tcp_conn_t *conn, tcp_segment_t *seg) 464 478 { 465 /* TODO */ 466 return cp_continue; 479 if ((seg->ctrl & CTL_SYN) == 0) 480 return cp_continue; 481 482 /* 483 * Assert SYN is in receive window, otherwise this step should not 484 * be reached. 485 */ 486 assert(seq_no_in_rcv_wnd(conn, seg->seq)); 487 488 log_msg(LVL_WARN, "SYN is in receive window, should send reset. XXX"); 489 490 /* 491 * TODO 492 * 493 * Send a reset, resond "reset" to all outstanding RECEIVEs and SEND, 494 * flush segment queues. Send unsolicited "connection reset" signal 495 * to user, connection -> closed state, delete TCB, return. 496 */ 497 return cp_done; 467 498 } 468 499 … … 790 821 { 791 822 log_msg(LVL_DEBUG, "tcp_conn_seg_proc_fin(%p, %p)", conn, seg); 823 log_msg(LVL_DEBUG, " seg->len=%zu, seg->ctl=%u", (size_t) seg->len, 824 (unsigned) seg->ctrl); 792 825 793 826 /* Only process FIN if no text is left in segment. */ … … 896 929 * incoming segments queue. 897 930 */ 898 if (seg->len > 0) 931 if (seg->len > 0) { 932 log_msg(LVL_DEBUG, "Re-insert segment %p. seg->len=%zu", 933 seg, (size_t) seg->len); 899 934 tcp_iqueue_insert_seg(&conn->incoming, seg); 900 else935 } else { 901 936 tcp_segment_delete(seg); 937 } 902 938 } 903 939 … … 927 963 tcp_conn_sa_queue(conn, seg); break; 928 964 case st_closed: 965 log_msg(LVL_DEBUG, "state=%d", (int) conn->cstate); 929 966 assert(false); 930 967 } -
uspace/srv/net/tl/tcp/ncsim.c
r8218b6b r7cf7ded 48 48 #include "ncsim.h" 49 49 #include "rqueue.h" 50 #include "segment.h" 50 51 #include "tcp_type.h" 51 52 … … 73 74 link_t *link; 74 75 75 log_msg(LVL_DEBUG, "tcp_ncsim_insert_seg()"); 76 log_msg(LVL_DEBUG, "tcp_ncsim_bounce_seg()"); 77 tcp_rqueue_bounce_seg(sp, seg); 78 return; 79 80 if (0 /*random() % 4 == 3*/) { 81 /* Drop segment */ 82 log_msg(LVL_ERROR, "NCSim dropping segment"); 83 tcp_segment_delete(seg); 84 return; 85 } 76 86 77 87 sqe = calloc(1, sizeof(tcp_squeue_entry_t)); -
uspace/srv/net/tl/tcp/seq_no.c
r8218b6b r7cf7ded 88 88 } 89 89 90 /** Determine if sequence number is in receive window. */ 91 bool seq_no_in_rcv_wnd(tcp_conn_t *conn, uint32_t sn) 92 { 93 return seq_no_le_lt(conn->rcv_nxt, sn, conn->rcv_nxt + conn->rcv_wnd); 94 } 95 90 96 /** Determine segment has new window update. 91 97 * -
uspace/srv/net/tl/tcp/seq_no.h
r8218b6b r7cf7ded 41 41 extern bool seq_no_ack_acceptable(tcp_conn_t *, uint32_t); 42 42 extern bool seq_no_ack_duplicate(tcp_conn_t *, uint32_t); 43 extern bool seq_no_in_rcv_wnd(tcp_conn_t *, uint32_t); 43 44 extern bool seq_no_new_wnd_update(tcp_conn_t *, tcp_segment_t *); 44 45 extern bool seq_no_segment_acked(tcp_conn_t *, tcp_segment_t *, uint32_t); -
uspace/srv/net/tl/tcp/state.c
r8218b6b r7cf7ded 112 112 log_msg(LVL_DEBUG, "tcp_uc_receive()"); 113 113 114 /* 115 * XXX Handle all states for all user calls properly, return 116 * errors as appropriate. 117 */ 118 if (conn->cstate == st_closed) 119 return; 120 121 114 122 fibril_mutex_lock(&conn->rcv_buf_lock); 115 123 … … 186 194 187 195 conn = tcp_conn_find(sp); 188 if (conn != NULL ) {196 if (conn != NULL && conn->cstate != st_closed) { 189 197 tcp_conn_segment_arrived(conn, seg); 190 198 } else { -
uspace/srv/net/tl/tcp/tcp_type.h
r8218b6b r7cf7ded 94 94 } tcp_sockpair_t; 95 95 96 /** Connection incoming segments queue */ 96 97 typedef struct { 97 98 struct tcp_conn *conn; … … 99 100 } tcp_iqueue_t; 100 101 102 /** Retransmission queue */ 101 103 typedef struct { 102 104 struct tcp_conn *conn; 103 105 list_t list; 106 107 /** Retransmission timer */ 108 fibril_timer_t *timer; 104 109 } tcp_tqueue_t; 105 110 106 111 typedef struct tcp_conn { 112 char *name; 107 113 link_t link; 108 114 … … 221 227 } tcp_iqueue_entry_t; 222 228 223 typedef struct { 224 link_t link; 229 /** Retransmission queue entry */ 230 typedef struct { 231 link_t link; 232 tcp_conn_t *conn; 225 233 tcp_segment_t *seg; 226 234 } tcp_tqueue_entry_t; -
uspace/srv/net/tl/tcp/test.c
r8218b6b r7cf7ded 59 59 sock.addr.ipv4 = 0x7f000001; 60 60 tcp_uc_open(80, &sock, ap_passive, &conn); 61 conn->name = (char *) "S"; 61 62 62 63 while (true) { … … 73 74 } 74 75 75 async_usleep( 1000*1000);76 async_usleep(/*10**/1000*1000); 76 77 77 78 printf("test_srv() close connection\n"); … … 94 95 async_usleep(1000*1000*3); 95 96 tcp_uc_open(1024, &sock, ap_active, &conn); 97 conn->name = (char *) "C"; 96 98 97 99 async_usleep(1000*1000*10); 98 100 tcp_uc_send(conn, (void *)msg, str_size(msg), 0); 99 101 100 async_usleep(1000*1000*3 );102 async_usleep(1000*1000*3/**20*2*/); 101 103 tcp_uc_close(conn); 102 104 } -
uspace/srv/net/tl/tcp/tqueue.c
r8218b6b r7cf7ded 36 36 37 37 #include <adt/list.h> 38 #include <errno.h> 39 #include <fibril_synch.h> 38 40 #include <byteorder.h> 39 41 #include <io/log.h> … … 50 52 #include "tcp_type.h" 51 53 52 void tcp_tqueue_init(tcp_tqueue_t *tqueue, tcp_conn_t *conn) 54 #define RETRANSMIT_TIMEOUT (2*1000*1000) 55 56 static void retransmit_timeout_func(void *arg); 57 static void tcp_tqueue_timer_set(tcp_conn_t *conn); 58 static void tcp_tqueue_timer_clear(tcp_conn_t *conn); 59 60 int tcp_tqueue_init(tcp_tqueue_t *tqueue, tcp_conn_t *conn) 53 61 { 54 62 tqueue->conn = conn; 63 tqueue->timer = fibril_timer_create(); 64 if (tqueue->timer == NULL) 65 return ENOMEM; 66 55 67 list_initialize(&tqueue->list); 68 69 return EOK; 70 } 71 72 void tcp_tqueue_fini(tcp_tqueue_t *tqueue) 73 { 74 if (tqueue->timer != NULL) { 75 fibril_timer_destroy(tqueue->timer); 76 tqueue->timer = NULL; 77 } 56 78 } 57 79 … … 92 114 } 93 115 116 tqe->conn = conn; 94 117 tqe->seg = rt_seg; 95 118 list_append(&tqe->link, &conn->retransmit.list); 96 } 97 119 120 /* Set retransmission timer */ 121 tcp_tqueue_timer_set(conn); 122 } 123 124 tcp_prepare_transmit_segment(conn, seg); 125 } 126 127 void tcp_prepare_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg) 128 { 98 129 /* 99 130 * Always send ACK once we have received SYN, except for RST segments. … … 105 136 106 137 seg->seq = conn->snd_nxt; 107 seg->wnd = conn->rcv_wnd;108 109 log_msg(LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,110 seg->seq, seg->wnd);111 112 if ((seg->ctrl & CTL_ACK) != 0)113 seg->ack = conn->rcv_nxt;114 else115 seg->ack = 0;116 117 138 conn->snd_nxt += seg->len; 118 139 … … 204 225 tcp_segment_delete(tqe->seg); 205 226 free(tqe); 227 228 /* Reset retransmission timer */ 229 tcp_tqueue_timer_set(conn); 206 230 } 207 231 208 232 cur = next; 209 233 } 234 235 /* Clear retransmission timer if the queue is empty. */ 236 if (list_empty(&conn->retransmit.list)) 237 tcp_tqueue_timer_clear(conn); 210 238 211 239 /* Possibly transmit more data */ … … 213 241 } 214 242 243 void tcp_conn_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg) 244 { 245 log_msg(LVL_DEBUG, "tcp_conn_transmit_segment(%p, %p)", conn, seg); 246 247 seg->wnd = conn->rcv_wnd; 248 249 if ((seg->ctrl & CTL_ACK) != 0) 250 seg->ack = conn->rcv_nxt; 251 else 252 seg->ack = 0; 253 254 tcp_transmit_segment(&conn->ident, seg); 255 } 256 215 257 void tcp_transmit_segment(tcp_sockpair_t *sp, tcp_segment_t *seg) 216 258 { 217 259 log_msg(LVL_DEBUG, "tcp_transmit_segment(%p, %p)", sp, seg); 260 261 log_msg(LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32, 262 seg->seq, seg->wnd); 218 263 /* 219 264 tcp_pdu_prepare(conn, seg, &data, &len); 220 265 tcp_pdu_transmit(data, len); 221 266 */ 222 //tcp_rqueue_bounce_seg(sp, seg); 223 tcp_ncsim_bounce_seg(sp, seg); 267 tcp_rqueue_bounce_seg(sp, seg); 268 // tcp_ncsim_bounce_seg(sp, seg); 269 } 270 271 static void retransmit_timeout_func(void *arg) 272 { 273 tcp_conn_t *conn = (tcp_conn_t *) arg; 274 tcp_tqueue_entry_t *tqe; 275 tcp_segment_t *rt_seg; 276 link_t *link; 277 278 log_msg(LVL_DEBUG, "### %s: retransmit_timeout_func(%p)", conn->name, conn); 279 link = list_first(&conn->retransmit.list); 280 if (link == NULL) { 281 log_msg(LVL_DEBUG, "Nothing to retransmit"); 282 return; 283 } 284 285 tqe = list_get_instance(link, tcp_tqueue_entry_t, link); 286 287 rt_seg = tcp_segment_dup(tqe->seg); 288 if (rt_seg == NULL) { 289 log_msg(LVL_ERROR, "Memory allocation failed."); 290 /* XXX Handle properly */ 291 return; 292 } 293 294 log_msg(LVL_DEBUG, "### %s: retransmitting segment", conn->name); 295 tcp_conn_transmit_segment(tqe->conn, rt_seg); 296 297 /* Reset retransmission timer */ 298 tcp_tqueue_timer_set(tqe->conn); 299 } 300 301 /** Set or re-set retransmission timer */ 302 static void tcp_tqueue_timer_set(tcp_conn_t *conn) 303 { 304 log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_set()", conn->name); 305 306 (void) retransmit_timeout_func; 307 fibril_timer_set(conn->retransmit.timer, RETRANSMIT_TIMEOUT, 308 retransmit_timeout_func, (void *) conn); 309 } 310 311 /** Clear retransmission timer */ 312 static void tcp_tqueue_timer_clear(tcp_conn_t *conn) 313 { 314 log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_clear()", conn->name); 315 316 fibril_timer_clear(conn->retransmit.timer); 224 317 } 225 318 -
uspace/srv/net/tl/tcp/tqueue.h
r8218b6b r7cf7ded 39 39 #include "tcp_type.h" 40 40 41 extern void tcp_tqueue_init(tcp_tqueue_t *, tcp_conn_t *); 41 extern int tcp_tqueue_init(tcp_tqueue_t *, tcp_conn_t *); 42 extern void tcp_tqueue_fini(tcp_tqueue_t *); 42 43 extern void tcp_tqueue_ctrl_seg(tcp_conn_t *, tcp_control_t); 43 44 extern void tcp_tqueue_seg(tcp_conn_t *, tcp_segment_t *); 44 45 extern void tcp_tqueue_new_data(tcp_conn_t *); 45 46 extern void tcp_tqueue_ack_received(tcp_conn_t *); 47 extern void tcp_prepare_transmit_segment(tcp_conn_t *, tcp_segment_t *); 48 extern void tcp_conn_transmit_segment(tcp_conn_t *, tcp_segment_t *); 46 49 extern void tcp_transmit_segment(tcp_sockpair_t *, tcp_segment_t *); 47 50 extern void tcp_header_setup(tcp_conn_t *, tcp_segment_t *, tcp_header_t *);
Note:
See TracChangeset
for help on using the changeset viewer.