Changeset 0093ab6 in mainline for uspace/srv/net/tl/tcp/conn.c


Ignore:
Timestamp:
2011-09-21T19:56:41Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
032bbe7
Parents:
4c55a64
Message:

Parts of data reception. Trimming segment to receive window.

File:
1 edited

Legend:

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

    r4c55a64 r0093ab6  
    3838#include <errno.h>
    3939#include <io/log.h>
     40#include <macros.h>
    4041#include <stdlib.h>
    4142#include "conn.h"
     
    4647#include "tqueue.h"
    4748
     49#define RCV_BUF_SIZE 4096
     50
    4851LIST_INITIALIZE(conn_list);
    4952
     
    5457        tcp_conn_t *conn;
    5558
     59        /* Allocate connection structure */
    5660        conn = calloc(1, sizeof(tcp_conn_t));
    5761        if (conn == NULL)
    5862                return NULL;
    5963
     64        /* Allocate receive buffer */
     65        conn->rcv_buf_size = RCV_BUF_SIZE;
     66        conn->rcv_buf_used = 0;
     67        conn->rcv_buf = calloc(1, conn->rcv_buf_size);
     68        if (conn->rcv_buf == NULL) {
     69                free(conn);
     70                return NULL;
     71        }
     72
     73        /* Set up receive window. */
     74        conn->rcv_wnd = conn->rcv_buf_size;
     75
     76        /* Initialize incoming segment queue */
    6077        tcp_iqueue_init(&conn->incoming, conn);
    6178
     
    175192
    176193        tcp_tqueue_ctrl_seg(conn, CTL_SYN | CTL_ACK /* XXX */);
     194
     195        tcp_segment_delete(seg);
    177196}
    178197
     
    225244                tcp_tqueue_ctrl_seg(conn, CTL_SYN | CTL_ACK /* XXX */);
    226245        }
     246
     247        tcp_segment_delete(seg);
    227248}
    228249
     
    288309static cproc_t tcp_conn_seg_proc_ack_est(tcp_conn_t *conn, tcp_segment_t *seg)
    289310{
     311        log_msg(LVL_DEBUG, "tcp_conn_seg_proc_ack_est(%p, %p)", conn, seg);
     312
     313        log_msg(LVL_DEBUG, "SEG.ACK=%u, SND.UNA=%u, SND.NXT=%u",
     314            (unsigned)seg->ack, (unsigned)conn->snd_una,
     315            (unsigned)conn->snd_nxt);
     316
    290317        if (!seq_no_ack_acceptable(conn, seg->ack)) {
     318                log_msg(LVL_DEBUG, "ACK not acceptable.");
    291319                if (!seq_no_ack_duplicate(conn, seg->ack)) {
     320                        log_msg(LVL_WARN, "Not acceptable, not duplicate. "
     321                            "Send ACK and drop.");
    292322                        /* Not acceptable, not duplicate. Send ACK and drop. */
    293323                        tcp_tqueue_ctrl_seg(conn, CTL_ACK);
    294324                        tcp_segment_delete(seg);
    295325                        return cp_done;
     326                } else {
     327                        log_msg(LVL_DEBUG, "Ignoring duplicate ACK.");
    296328                }
    297329        } else {
     
    401433}
    402434
     435/** Process segment text. */
    403436static cproc_t tcp_conn_seg_proc_text(tcp_conn_t *conn, tcp_segment_t *seg)
    404437{
     438        size_t text_size;
     439        size_t xfer_size;
     440
     441        log_msg(LVL_DEBUG, "tcp_conn_seg_proc_text(%p, %p)", conn, seg);
     442
    405443        switch (conn->cstate) {
    406444        case st_established:
     
    422460        }
    423461
    424         /* TODO Process segment text */
     462        /*
     463         * Process segment text
     464         */
     465        assert(seq_no_segment_ready(conn, seg));
     466
     467        /* Trim anything outside our receive window */
     468        tcp_conn_trim_seg_to_wnd(conn, seg);
     469
     470        /* Determine how many bytes to copy */
     471        text_size = tcp_segment_text_size(seg);
     472        xfer_size = min(text_size, conn->rcv_buf_size - conn->rcv_buf_used);
     473
     474        /* Copy data to receive buffer */
     475        tcp_segment_text_copy(seg, conn->rcv_buf, xfer_size);
     476
     477        /* Advance RCV.NXT */
     478        conn->rcv_nxt += xfer_size;
     479
     480        /* Update receive window. XXX Not an efficient strategy. */
     481        conn->rcv_wnd -= xfer_size;
     482
     483        /* XXX Signal user that some data arrived. */
     484
     485        /* Send ACK */
     486        if (xfer_size > 0)
     487                tcp_tqueue_ctrl_seg(conn, CTL_ACK);
     488
     489        /* Anything left in the segment? (text, FIN) */
     490        if (xfer_size < seg->len) {
     491                /*
     492                 * Some text or control remains. Insert remainder back
     493                 * into the incoming queue.
     494                 */
     495                tcp_conn_trim_seg_to_wnd(conn, seg);
     496                tcp_iqueue_insert_seg(&conn->incoming, seg);
     497
     498                return cp_done;
     499        }
     500
    425501        return cp_continue;
    426502}
     
    472548        if (tcp_conn_seg_proc_fin(conn, seg) == cp_done)
    473549                return;
     550
     551        tcp_segment_delete(seg);
    474552}
    475553
     
    498576}
    499577
     578void tcp_conn_trim_seg_to_wnd(tcp_conn_t *conn, tcp_segment_t *seg)
     579{
     580        uint32_t left, right;
     581
     582        seq_no_seg_trim_calc(conn, seg, &left, &right);
     583        tcp_segment_trim(seg, left, right);
     584}
     585
    500586void tcp_unexpected_segment(tcp_sockpair_t *sp, tcp_segment_t *seg)
    501587{
Note: See TracChangeset for help on using the changeset viewer.