Changeset 8c7a054 in mainline
- Timestamp:
- 2011-10-21T15:25:43Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 32aea9f4
- Parents:
- d9ce049
- Location:
- uspace/srv/net/tl/tcp
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/conn.c
rd9ce049 r8c7a054 36 36 37 37 #include <adt/list.h> 38 #include <bool.h> 38 39 #include <errno.h> 39 40 #include <io/log.h> … … 74 75 conn->rcv_buf_size = RCV_BUF_SIZE; 75 76 conn->rcv_buf_used = 0; 77 conn->rcv_buf_fin = false; 76 78 77 79 conn->rcv_buf = calloc(1, conn->rcv_buf_size); … … 84 86 conn->snd_buf_size = SND_BUF_SIZE; 85 87 conn->snd_buf_used = 0; 88 conn->snd_buf_fin = false; 86 89 conn->snd_buf = calloc(1, conn->snd_buf_size); 87 90 if (conn->snd_buf == NULL) { … … 697 700 conn->rcv_wnd -= xfer_size; 698 701 699 /* XXX Signal user that some data arrived. */700 701 702 /* Send ACK */ 702 703 if (xfer_size > 0) 703 704 tcp_tqueue_ctrl_seg(conn, CTL_ACK); 704 705 705 /* Anything left in the segment? (text, FIN) */706 706 if (xfer_size < seg->len) { 707 /* 708 * Some text or control remains. Insert remainder back 709 * into the incoming queue. 710 */ 707 /* Trim part of segment which we just received */ 711 708 tcp_conn_trim_seg_to_wnd(conn, seg); 712 tcp_iqueue_insert_seg(&conn->incoming, seg); 713 709 } else { 710 /* Nothing left in segment */ 711 tcp_segment_delete(seg); 714 712 return cp_done; 715 713 } … … 727 725 static cproc_t tcp_conn_seg_proc_fin(tcp_conn_t *conn, tcp_segment_t *seg) 728 726 { 727 log_msg(LVL_DEBUG, "tcp_conn_seg_proc_fin(%p, %p)", conn, seg); 728 729 /* Only process FIN if no text is left in segment. */ 730 if (tcp_segment_text_size(seg) == 0 && (seg->ctrl & CTL_FIN) != 0) { 731 log_msg(LVL_DEBUG, " - FIN found in segment."); 732 733 conn->rcv_nxt++; 734 conn->rcv_wnd--; 735 736 /* TODO Change connection state */ 737 738 /* Add FIN to the receive buffer */ 739 fibril_mutex_lock(&conn->rcv_buf_lock); 740 conn->rcv_buf_fin = true; 741 fibril_condvar_broadcast(&conn->rcv_buf_cv); 742 fibril_mutex_unlock(&conn->rcv_buf_lock); 743 744 tcp_segment_delete(seg); 745 return cp_done; 746 } 747 729 748 return cp_continue; 730 749 } … … 775 794 return; 776 795 777 tcp_segment_delete(seg); 796 /* 797 * If anything is left from the segment, insert it back into the 798 * incoming segments queue. 799 */ 800 if (seg->len > 0) 801 tcp_iqueue_insert_seg(&conn->incoming, seg); 802 else 803 tcp_segment_delete(seg); 778 804 } 779 805 -
uspace/srv/net/tl/tcp/segment.c
rd9ce049 r8c7a054 99 99 tcp_segment_t *seg; 100 100 101 assert( size > 0);101 assert(ctrl != 0 || size > 0); 102 102 103 103 seg = tcp_segment_new(); -
uspace/srv/net/tl/tcp/state.c
rd9ce049 r8c7a054 115 115 116 116 /* Wait for data to become available */ 117 while (conn->rcv_buf_used == 0 ) {117 while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin) { 118 118 log_msg(LVL_DEBUG, "tcp_uc_receive() - wait for data"); 119 119 fibril_condvar_wait(&conn->rcv_buf_cv, &conn->rcv_buf_lock); 120 } 121 122 if (conn->rcv_buf_used == 0) { 123 /* End of data, peer closed connection. */ 124 /* XXX How should RECEIVE signal end of data? */ 125 assert(conn->rcv_buf_fin); 126 *rcvd = 0; 127 *xflags = 0; 128 return; 120 129 } 121 130 … … 147 156 { 148 157 log_msg(LVL_DEBUG, "tcp_uc_close()"); 158 159 conn->snd_buf_fin = true; 160 tcp_tqueue_new_data(conn); 149 161 } 150 162 -
uspace/srv/net/tl/tcp/tcp_type.h
rd9ce049 r8c7a054 37 37 38 38 #include <adt/list.h> 39 #include <bool.h> 39 40 #include <fibril_synch.h> 40 41 #include <sys/types.h> … … 114 115 /** Receive buffer size */ 115 116 size_t rcv_buf_size; 117 /** Receive buffer number of bytes used */ 116 118 size_t rcv_buf_used; 119 /** Receive buffer contains FIN */ 120 bool rcv_buf_fin; 121 /** Receive buffer lock */ 117 122 fibril_mutex_t rcv_buf_lock; 123 /** Receive buffer CV. Broadcast when new data is inserted */ 118 124 fibril_condvar_t rcv_buf_cv; 119 125 … … 122 128 /** Send buffer size */ 123 129 size_t snd_buf_size; 130 /** Send buffer number of bytes used */ 124 131 size_t snd_buf_used; 132 /** Send buffer contains FIN */ 133 bool snd_buf_fin; 125 134 126 135 /** Send unacknowledged */ -
uspace/srv/net/tl/tcp/test.c
rd9ce049 r8c7a054 63 63 printf("User receive...\n"); 64 64 tcp_uc_receive(conn, rcv_buf, RCV_BUF_SIZE, &rcvd, &xflags); 65 if (rcvd == 0) { 66 printf("End of data reached.\n"); 67 break; 68 } 65 69 rcv_buf[rcvd] = '\0'; 66 70 printf("User received %zu bytes '%s'.\n", rcvd, rcv_buf); … … 68 72 async_usleep(1000*1000*2); 69 73 } 74 75 printf("test_srv() terminating\n"); 70 76 } 71 77 … … 80 86 sock.port = 80; 81 87 sock.addr.ipv4 = 0x7f000001; 82 88 83 89 async_usleep(1000*1000*3); 84 90 tcp_uc_open(1024, &sock, ap_active, &conn); … … 86 92 async_usleep(1000*1000*10); 87 93 tcp_uc_send(conn, (void *)msg, str_size(msg), 0); 94 95 async_usleep(1000*1000*3); 96 tcp_uc_close(conn); 88 97 } 89 98 -
uspace/srv/net/tl/tcp/tqueue.c
rd9ce049 r8c7a054 92 92 { 93 93 size_t avail_wnd; 94 size_t xfer_seqlen; 95 size_t snd_buf_seqlen; 94 96 size_t data_size; 97 tcp_control_t ctrl; 98 95 99 tcp_segment_t *seg; 96 100 … … 99 103 /* Number of free sequence numbers in send window */ 100 104 avail_wnd = (conn->snd_una + conn->snd_wnd) - conn->snd_nxt; 105 snd_buf_seqlen = conn->snd_buf_used + (conn->snd_buf_fin ? 1 : 0); 101 106 102 data_size = min(conn->snd_buf_used, avail_wnd); 103 log_msg(LVL_DEBUG, "conn->snd_buf_used = %zu, SND.WND = %zu, " 104 "data_size = %zu", conn->snd_buf_used, conn->snd_wnd, data_size); 107 xfer_seqlen = min(snd_buf_seqlen, avail_wnd); 108 log_msg(LVL_DEBUG, "snd_buf_seqlen = %zu, SND.WND = %zu, " 109 "xfer_seqlen = %zu", snd_buf_seqlen, conn->snd_wnd, 110 xfer_seqlen); 105 111 106 if ( data_size== 0)112 if (xfer_seqlen == 0) 107 113 return; 108 114 109 115 /* XXX Do not always send immediately */ 110 116 111 seg = tcp_segment_make_data(0, conn->snd_buf, data_size); 117 data_size = xfer_seqlen - (conn->snd_buf_fin ? 1 : 0); 118 if (conn->snd_buf_fin && data_size + 1 == xfer_seqlen) { 119 /* We are sending out FIN */ 120 ctrl = CTL_FIN; 121 } else { 122 ctrl = 0; 123 } 124 125 seg = tcp_segment_make_data(ctrl, conn->snd_buf, data_size); 112 126 if (seg == NULL) { 113 127 log_msg(LVL_ERROR, "Memory allocation failure."); … … 119 133 conn->snd_buf_used - data_size); 120 134 conn->snd_buf_used -= data_size; 135 conn->snd_buf_fin = false; 121 136 122 137 tcp_tqueue_seg(conn, seg);
Note:
See TracChangeset
for help on using the changeset viewer.