Changeset 8c7a054 in mainline


Ignore:
Timestamp:
2011-10-21T15:25:43Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
32aea9f4
Parents:
d9ce049
Message:

FIN processing (WIP).

Location:
uspace/srv/net/tl/tcp
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/tcp/conn.c

    rd9ce049 r8c7a054  
    3636
    3737#include <adt/list.h>
     38#include <bool.h>
    3839#include <errno.h>
    3940#include <io/log.h>
     
    7475        conn->rcv_buf_size = RCV_BUF_SIZE;
    7576        conn->rcv_buf_used = 0;
     77        conn->rcv_buf_fin = false;
    7678
    7779        conn->rcv_buf = calloc(1, conn->rcv_buf_size);
     
    8486        conn->snd_buf_size = SND_BUF_SIZE;
    8587        conn->snd_buf_used = 0;
     88        conn->snd_buf_fin = false;
    8689        conn->snd_buf = calloc(1, conn->snd_buf_size);
    8790        if (conn->snd_buf == NULL) {
     
    697700        conn->rcv_wnd -= xfer_size;
    698701
    699         /* XXX Signal user that some data arrived. */
    700 
    701702        /* Send ACK */
    702703        if (xfer_size > 0)
    703704                tcp_tqueue_ctrl_seg(conn, CTL_ACK);
    704705
    705         /* Anything left in the segment? (text, FIN) */
    706706        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 */
    711708                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);
    714712                return cp_done;
    715713        }
     
    727725static cproc_t tcp_conn_seg_proc_fin(tcp_conn_t *conn, tcp_segment_t *seg)
    728726{
     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
    729748        return cp_continue;
    730749}
     
    775794                return;
    776795
    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);
    778804}
    779805
  • uspace/srv/net/tl/tcp/segment.c

    rd9ce049 r8c7a054  
    9999        tcp_segment_t *seg;
    100100
    101         assert(size > 0);
     101        assert(ctrl != 0 || size > 0);
    102102
    103103        seg = tcp_segment_new();
  • uspace/srv/net/tl/tcp/state.c

    rd9ce049 r8c7a054  
    115115
    116116        /* Wait for data to become available */
    117         while (conn->rcv_buf_used == 0) {
     117        while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin) {
    118118                log_msg(LVL_DEBUG, "tcp_uc_receive() - wait for data");
    119119                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;
    120129        }
    121130
     
    147156{
    148157        log_msg(LVL_DEBUG, "tcp_uc_close()");
     158
     159        conn->snd_buf_fin = true;
     160        tcp_tqueue_new_data(conn);
    149161}
    150162
  • uspace/srv/net/tl/tcp/tcp_type.h

    rd9ce049 r8c7a054  
    3737
    3838#include <adt/list.h>
     39#include <bool.h>
    3940#include <fibril_synch.h>
    4041#include <sys/types.h>
     
    114115        /** Receive buffer size */
    115116        size_t rcv_buf_size;
     117        /** Receive buffer number of bytes used */
    116118        size_t rcv_buf_used;
     119        /** Receive buffer contains FIN */
     120        bool rcv_buf_fin;
     121        /** Receive buffer lock */
    117122        fibril_mutex_t rcv_buf_lock;
     123        /** Receive buffer CV. Broadcast when new data is inserted */
    118124        fibril_condvar_t rcv_buf_cv;
    119125
     
    122128        /** Send buffer size */
    123129        size_t snd_buf_size;
     130        /** Send buffer number of bytes used */
    124131        size_t snd_buf_used;
     132        /** Send buffer contains FIN */
     133        bool snd_buf_fin;
    125134
    126135        /** Send unacknowledged */
  • uspace/srv/net/tl/tcp/test.c

    rd9ce049 r8c7a054  
    6363                printf("User receive...\n");
    6464                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                }
    6569                rcv_buf[rcvd] = '\0';
    6670                printf("User received %zu bytes '%s'.\n", rcvd, rcv_buf);
     
    6872                async_usleep(1000*1000*2);
    6973        }
     74
     75        printf("test_srv() terminating\n");
    7076}
    7177
     
    8086        sock.port = 80;
    8187        sock.addr.ipv4 = 0x7f000001;
    82        
     88
    8389        async_usleep(1000*1000*3);
    8490        tcp_uc_open(1024, &sock, ap_active, &conn);
     
    8692        async_usleep(1000*1000*10);
    8793        tcp_uc_send(conn, (void *)msg, str_size(msg), 0);
     94
     95        async_usleep(1000*1000*3);
     96        tcp_uc_close(conn);
    8897}
    8998
  • uspace/srv/net/tl/tcp/tqueue.c

    rd9ce049 r8c7a054  
    9292{
    9393        size_t avail_wnd;
     94        size_t xfer_seqlen;
     95        size_t snd_buf_seqlen;
    9496        size_t data_size;
     97        tcp_control_t ctrl;
     98
    9599        tcp_segment_t *seg;
    96100
     
    99103        /* Number of free sequence numbers in send window */
    100104        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);
    101106
    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);
    105111
    106         if (data_size == 0)
     112        if (xfer_seqlen == 0)
    107113                return;
    108114
    109115        /* XXX Do not always send immediately */
    110116
    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);
    112126        if (seg == NULL) {
    113127                log_msg(LVL_ERROR, "Memory allocation failure.");
     
    119133            conn->snd_buf_used - data_size);
    120134        conn->snd_buf_used -= data_size;
     135        conn->snd_buf_fin = false;
    121136
    122137        tcp_tqueue_seg(conn, seg);
Note: See TracChangeset for help on using the changeset viewer.