Changeset d9ce049 in mainline


Ignore:
Timestamp:
2011-10-04T20:40:05Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8c7a054
Parents:
32105348
Message:

Implement RECEIVE user call.

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

Legend:

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

    r32105348 rd9ce049  
    7070
    7171        /* Allocate receive buffer */
     72        fibril_mutex_initialize(&conn->rcv_buf_lock);
     73        fibril_condvar_initialize(&conn->rcv_buf_cv);
    7274        conn->rcv_buf_size = RCV_BUF_SIZE;
    7375        conn->rcv_buf_used = 0;
     76
    7477        conn->rcv_buf = calloc(1, conn->rcv_buf_size);
    7578        if (conn->rcv_buf == NULL) {
     
    306309        if ((seg->ctrl & CTL_ACK) != 0) {
    307310                conn->snd_una = seg->ack;
    308                 tcp_tqueue_remove_acked(conn);
     311
     312                /*
     313                 * Prune acked segments from retransmission queue and
     314                 * possibly transmit more data.
     315                 */
     316                tcp_tqueue_ack_received(conn);
    309317        }
    310318
     
    459467                /* Update SND.UNA */
    460468                conn->snd_una = seg->ack;
    461 
    462                 /* Prune acked segments from retransmission queue */
    463                 tcp_tqueue_remove_acked(conn);
    464469        }
    465470
     
    468473                conn->snd_wl1 = seg->seq;
    469474                conn->snd_wl2 = seg->ack;
    470         }
     475
     476                log_msg(LVL_DEBUG, "Updating send window, SND.WND=%" PRIu32
     477                    ", SND.WL1=%" PRIu32 ", SND.WL2=%" PRIu32,
     478                    conn->snd_wnd, conn->snd_wl1, conn->snd_wl2);
     479        }
     480
     481        /*
     482         * Prune acked segments from retransmission queue and
     483         * possibly transmit more data.
     484         */
     485        tcp_tqueue_ack_received(conn);
    471486
    472487        return cp_continue;
     
    659674        tcp_conn_trim_seg_to_wnd(conn, seg);
    660675
     676        fibril_mutex_lock(&conn->rcv_buf_lock);
     677
    661678        /* Determine how many bytes to copy */
    662679        text_size = tcp_segment_text_size(seg);
     
    664681
    665682        /* Copy data to receive buffer */
    666         tcp_segment_text_copy(seg, conn->rcv_buf, xfer_size);
     683        tcp_segment_text_copy(seg, conn->rcv_buf + conn->rcv_buf_used,
     684            xfer_size);
     685        conn->rcv_buf_used += xfer_size;
     686
     687        /* Signal to the receive function that new data has arrived */
     688        fibril_condvar_broadcast(&conn->rcv_buf_cv);
     689        fibril_mutex_unlock(&conn->rcv_buf_lock);
    667690
    668691        log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
  • uspace/srv/net/tl/tcp/iqueue.c

    r32105348 rd9ce049  
    104104
    105105        while (!seq_no_segment_acceptable(iqueue->conn, iqe->seg)) {
    106                 log_msg(LVL_DEBUG, "Skipping unacceptable segment");
     106                log_msg(LVL_DEBUG, "Skipping unacceptable segment (RCV.NXT=%"
     107                    PRIu32 ", RCV.NXT+RCV.WND=%" PRIu32 ", SEG.SEQ=%" PRIu32
     108                    ", SEG.LEN=%" PRIu32 ")", iqueue->conn->rcv_nxt,
     109                    iqueue->conn->rcv_nxt + iqueue->conn->rcv_wnd,
     110                    iqe->seg->seq, iqe->seg->len);
    107111
    108112                list_remove(&iqe->link);
  • uspace/srv/net/tl/tcp/state.c

    r32105348 rd9ce049  
    3535 */
    3636
     37#include <fibril_synch.h>
    3738#include <io/log.h>
    3839#include <macros.h>
     
    107108    xflags_t *xflags)
    108109{
     110        size_t xfer_size;
     111
    109112        log_msg(LVL_DEBUG, "tcp_uc_receive()");
     113
     114        fibril_mutex_lock(&conn->rcv_buf_lock);
     115
     116        /* Wait for data to become available */
     117        while (conn->rcv_buf_used == 0) {
     118                log_msg(LVL_DEBUG, "tcp_uc_receive() - wait for data");
     119                fibril_condvar_wait(&conn->rcv_buf_cv, &conn->rcv_buf_lock);
     120        }
     121
     122        /* Copy data from receive buffer to user buffer */
     123        xfer_size = min(size, conn->rcv_buf_used);
     124        memcpy(buf, conn->rcv_buf, xfer_size);
     125        *rcvd = xfer_size;
     126
     127        /* Remove data from receive buffer */
     128        memmove(conn->rcv_buf, conn->rcv_buf + xfer_size, conn->rcv_buf_used -
     129            xfer_size);
     130        conn->rcv_buf_used -= xfer_size;
     131        conn->rcv_wnd += xfer_size;
     132
     133        fibril_mutex_unlock(&conn->rcv_buf_lock);
     134
     135        /* TODO */
     136        *xflags = 0;
     137
     138        /* Send new size of receive window */
     139        tcp_tqueue_ctrl_seg(conn, CTL_ACK);
     140
     141        log_msg(LVL_DEBUG, "tcp_uc_receive() - returning %zu bytes",
     142            xfer_size);
    110143}
    111144
  • uspace/srv/net/tl/tcp/tcp_type.h

    r32105348 rd9ce049  
    3737
    3838#include <adt/list.h>
     39#include <fibril_synch.h>
    3940#include <sys/types.h>
    4041
     
    114115        size_t rcv_buf_size;
    115116        size_t rcv_buf_used;
     117        fibril_mutex_t rcv_buf_lock;
     118        fibril_condvar_t rcv_buf_cv;
    116119
    117120        /** Send buffer */
  • uspace/srv/net/tl/tcp/test.c

    r32105348 rd9ce049  
    4545#include "test.h"
    4646
     47#define RCV_BUF_SIZE 64
     48
    4749static void test_srv(void *arg)
    4850{
    4951        tcp_conn_t *conn;
    5052        tcp_sock_t sock;
     53        char rcv_buf[RCV_BUF_SIZE + 1];
     54        size_t rcvd;
     55        xflags_t xflags;
    5156
    5257        printf("test_srv()\n");
     
    5459        sock.addr.ipv4 = 0x7f000001;
    5560        tcp_uc_open(80, &sock, ap_passive, &conn);
     61
     62        while (true) {
     63                printf("User receive...\n");
     64                tcp_uc_receive(conn, rcv_buf, RCV_BUF_SIZE, &rcvd, &xflags);
     65                rcv_buf[rcvd] = '\0';
     66                printf("User received %zu bytes '%s'.\n", rcvd, rcv_buf);
     67
     68                async_usleep(1000*1000*2);
     69        }
    5670}
    5771
  • uspace/srv/net/tl/tcp/tqueue.c

    r32105348 rd9ce049  
    7272        seg->wnd = conn->rcv_wnd;
    7373
     74        log_msg(LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
     75            seg->seq, seg->wnd);
     76
    7477        if ((seg->ctrl & CTL_ACK) != 0)
    7578                seg->ack = conn->rcv_nxt;
     
    8891void tcp_tqueue_new_data(tcp_conn_t *conn)
    8992{
     93        size_t avail_wnd;
    9094        size_t data_size;
    9195        tcp_segment_t *seg;
     
    9397        log_msg(LVL_DEBUG, "tcp_tqueue_new_data()");
    9498
    95         data_size = min(conn->snd_buf_used, conn->snd_wnd);
     99        /* Number of free sequence numbers in send window */
     100        avail_wnd = (conn->snd_una + conn->snd_wnd) - conn->snd_nxt;
     101
     102        data_size = min(conn->snd_buf_used, avail_wnd);
    96103        log_msg(LVL_DEBUG, "conn->snd_buf_used = %zu, SND.WND = %zu, "
    97104            "data_size = %zu", conn->snd_buf_used, conn->snd_wnd, data_size);
     
    116123}
    117124
    118 /** Remove ACKed segments from retransmission queue.
     125/** Remove ACKed segments from retransmission queue and possibly transmit
     126 * more data.
    119127 *
    120128 * This should be called when SND.UNA is updated due to incoming ACK.
    121129 */
    122 void tcp_tqueue_remove_acked(tcp_conn_t *conn)
     130void tcp_tqueue_ack_received(tcp_conn_t *conn)
    123131{
    124132        (void) conn;
     133
     134        tcp_tqueue_new_data(conn);
    125135}
    126136
  • uspace/srv/net/tl/tcp/tqueue.h

    r32105348 rd9ce049  
    4242extern void tcp_tqueue_seg(tcp_conn_t *, tcp_segment_t *);
    4343extern void tcp_tqueue_new_data(tcp_conn_t *);
    44 extern void tcp_tqueue_remove_acked(tcp_conn_t *);
     44extern void tcp_tqueue_ack_received(tcp_conn_t *);
    4545extern void tcp_transmit_segment(tcp_sockpair_t *, tcp_segment_t *);
    4646extern void tcp_header_setup(tcp_conn_t *, tcp_segment_t *, tcp_header_t *);
Note: See TracChangeset for help on using the changeset viewer.