Changeset 32105348 in mainline


Ignore:
Timestamp:
2011-10-04T18:12:41Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d9ce049
Parents:
032bbe7
Message:

Send buffer, sketch data transmission.

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

Legend:

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

    r032bbe7 r32105348  
    4848
    4949#define RCV_BUF_SIZE 4096
     50#define SND_BUF_SIZE 4096
    5051
    5152LIST_INITIALIZE(conn_list);
     
    7778        }
    7879
     80        /** Allocate send buffer */
     81        conn->snd_buf_size = SND_BUF_SIZE;
     82        conn->snd_buf_used = 0;
     83        conn->snd_buf = calloc(1, conn->snd_buf_size);
     84        if (conn->snd_buf == NULL) {
     85                free(conn);
     86                return NULL;
     87        }
     88
    7989        /* Set up receive window. */
    8090        conn->rcv_wnd = conn->rcv_buf_size;
     
    171181
    172182        return NULL;
     183}
     184
     185/** Determine if SYN has been received.
     186 *
     187 * @param conn  Connection
     188 * @return      @c true if SYN has been received, @c false otherwise.
     189 */
     190bool tcp_conn_got_syn(tcp_conn_t *conn)
     191{
     192        switch (conn->cstate) {
     193        case st_listen:
     194        case st_syn_sent:
     195                return false;
     196        case st_syn_received:
     197        case st_established:
     198        case st_fin_wait_1:
     199        case st_fin_wait_2:
     200        case st_close_wait:
     201        case st_closing:
     202        case st_last_ack:
     203        case st_time_wait:
     204                return true;
     205        case st_closed:
     206                assert(false);
     207        }
     208
     209        assert(false);
    173210}
    174211
     
    273310
    274311        log_msg(LVL_DEBUG, "Sent SYN, got SYN.");
     312
     313        /*
     314         * Surprisingly the spec does not deal with initial window setting.
     315         * Set SND.WND = SEG.WND and set SND.WL1 so that next segment
     316         * will always be accepted as new window setting.
     317         */
     318        log_msg(LVL_DEBUG, "SND.WND := %" PRIu32 ", SND.WL1 := %" PRIu32 ", "
     319            "SND.WL2 = %" PRIu32, seg->wnd, seg->seq, seg->seq);
     320        conn->snd_wnd = seg->wnd;
     321        conn->snd_wl1 = seg->seq;
     322        conn->snd_wl2 = seg->seq;
    275323
    276324        if (seq_no_syn_acked(conn)) {
     
    618666        tcp_segment_text_copy(seg, conn->rcv_buf, xfer_size);
    619667
     668        log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
     669
    620670        /* Advance RCV.NXT */
    621671        conn->rcv_nxt += xfer_size;
     
    764814/** Compute flipped socket pair for response.
    765815 *
    766  * Flipped socket pair has local and foreign sockes exchanged.
     816 * Flipped socket pair has local and foreign sockets exchanged.
    767817 *
    768818 * @param sp            Socket pair
  • uspace/srv/net/tl/tcp/conn.h

    r032bbe7 r32105348  
    3636#define CONN_H
    3737
     38#include <bool.h>
    3839#include "tcp_type.h"
    3940
     
    4243extern void tcp_conn_sync(tcp_conn_t *);
    4344extern tcp_conn_t *tcp_conn_find(tcp_sockpair_t *);
     45extern bool tcp_conn_got_syn(tcp_conn_t *);
    4446extern void tcp_conn_segment_arrived(tcp_conn_t *, tcp_segment_t *);
    4547extern void tcp_conn_trim_seg_to_wnd(tcp_conn_t *, tcp_segment_t *);
  • uspace/srv/net/tl/tcp/segment.c

    r032bbe7 r32105348  
    5353}
    5454
    55 /** Create a control segment.
    56  *
    57   * @return     Control segment
     55/** Create a control-only segment.
     56 *
     57  * @return     Segment
    5858 */
    5959tcp_segment_t *tcp_segment_make_ctrl(tcp_control_t ctrl)
     
    8989        return rseg;
    9090}
     91
     92/** Create a control segment.
     93 *
     94  * @return     Segment
     95 */
     96tcp_segment_t *tcp_segment_make_data(tcp_control_t ctrl, void *data,
     97    size_t size)
     98{
     99        tcp_segment_t *seg;
     100
     101        assert(size > 0);
     102
     103        seg = tcp_segment_new();
     104        if (seg == NULL)
     105                return NULL;
     106
     107        seg->ctrl = ctrl;
     108        seg->len = seq_no_control_len(ctrl) + size;
     109
     110        seg->dfptr = seg->data = malloc(size);
     111        if (seg->dfptr == NULL) {
     112                free(seg);
     113                return NULL;
     114        }
     115
     116        memcpy(seg->data, data, size);
     117
     118        return seg;
     119}
     120
    91121
    92122/** Trim segment from left and right by the specified amount.
  • uspace/srv/net/tl/tcp/segment.h

    r032bbe7 r32105348  
    4343extern tcp_segment_t *tcp_segment_make_ctrl(tcp_control_t);
    4444extern tcp_segment_t *tcp_segment_make_rst(tcp_segment_t *);
     45extern tcp_segment_t *tcp_segment_make_data(tcp_control_t, void *, size_t);
    4546extern void tcp_segment_trim(tcp_segment_t *, uint32_t, uint32_t);
    4647extern void tcp_segment_text_copy(tcp_segment_t *, void *, size_t);
  • uspace/srv/net/tl/tcp/state.c

    r032bbe7 r32105348  
    3636
    3737#include <io/log.h>
     38#include <macros.h>
     39#include <mem.h>
    3840#include "conn.h"
    3941#include "state.h"
    4042#include "tcp_type.h"
     43#include "tqueue.h"
    4144
    4245/*
     
    7881void tcp_uc_send(tcp_conn_t *conn, void *data, size_t size, xflags_t flags)
    7982{
     83        size_t buf_free;
     84        size_t xfer_size;
     85
    8086        log_msg(LVL_DEBUG, "tcp_uc_send()");
     87
     88        while (size > 0) {
     89                buf_free = conn->snd_buf_size - conn->snd_buf_used;
     90                while (buf_free == 0)
     91                        tcp_tqueue_new_data(conn);
     92
     93                xfer_size = min(size, buf_free);
     94
     95                /* Copy data to buffer */
     96                memcpy(conn->snd_buf + conn->snd_buf_used, data, xfer_size);
     97                data += xfer_size;
     98                conn->snd_buf_used += xfer_size;
     99                size -= xfer_size;
     100        }
     101
     102        tcp_tqueue_new_data(conn);
    81103}
    82104
  • uspace/srv/net/tl/tcp/tcp_type.h

    r032bbe7 r32105348  
    115115        size_t rcv_buf_used;
    116116
     117        /** Send buffer */
     118        uint8_t *snd_buf;
     119        /** Send buffer size */
     120        size_t snd_buf_size;
     121        size_t snd_buf_used;
     122
    117123        /** Send unacknowledged */
    118124        uint32_t snd_una;
  • uspace/srv/net/tl/tcp/test.c

    r032bbe7 r32105348  
    3939#include <stdio.h>
    4040#include <thread.h>
     41#include <str.h>
    4142#include "state.h"
    4243#include "tcp_type.h"
     
    5960        tcp_conn_t *conn;
    6061        tcp_sock_t sock;
     62        const char *msg = "Hello World!";
    6163
    6264        printf("test_cli()\n");
     
    6769        async_usleep(1000*1000*3);
    6870        tcp_uc_open(1024, &sock, ap_active, &conn);
     71
     72        async_usleep(1000*1000*10);
     73        tcp_uc_send(conn, (void *)msg, str_size(msg), 0);
    6974}
    7075
  • uspace/srv/net/tl/tcp/tqueue.c

    r032bbe7 r32105348  
    3737#include <byteorder.h>
    3838#include <io/log.h>
     39#include <macros.h>
     40#include <mem.h>
     41#include "conn.h"
    3942#include "header.h"
    4043#include "rqueue.h"
     
    5053
    5154        seg = tcp_segment_make_ctrl(ctrl);
    52         seg->seq = conn->snd_nxt;
    53         seg->ack = conn->rcv_nxt;
    5455        tcp_tqueue_seg(conn, seg);
    5556}
     
    6061        /* XXX queue */
    6162
     63        /*
     64         * Always send ACK once we have received SYN, except for RST segments.
     65         * (Spec says we should always send ACK once connection has been
     66         * established.)
     67         */
     68        if (tcp_conn_got_syn(conn) && (seg->ctrl & CTL_RST) == 0)
     69                seg->ctrl |= CTL_ACK;
     70
     71        seg->seq = conn->snd_nxt;
     72        seg->wnd = conn->rcv_wnd;
     73
     74        if ((seg->ctrl & CTL_ACK) != 0)
     75                seg->ack = conn->rcv_nxt;
     76        else
     77                seg->ack = 0;
     78
    6279        conn->snd_nxt += seg->len;
     80
    6381        tcp_transmit_segment(&conn->ident, seg);
     82}
     83
     84/** Transmit data from the send buffer.
     85 *
     86 * @param conn  Connection
     87 */
     88void tcp_tqueue_new_data(tcp_conn_t *conn)
     89{
     90        size_t data_size;
     91        tcp_segment_t *seg;
     92
     93        log_msg(LVL_DEBUG, "tcp_tqueue_new_data()");
     94
     95        data_size = min(conn->snd_buf_used, conn->snd_wnd);
     96        log_msg(LVL_DEBUG, "conn->snd_buf_used = %zu, SND.WND = %zu, "
     97            "data_size = %zu", conn->snd_buf_used, conn->snd_wnd, data_size);
     98
     99        if (data_size == 0)
     100                return;
     101
     102        /* XXX Do not always send immediately */
     103
     104        seg = tcp_segment_make_data(0, conn->snd_buf, data_size);
     105        if (seg == NULL) {
     106                log_msg(LVL_ERROR, "Memory allocation failure.");
     107                return;
     108        }
     109
     110        /* Remove data from send buffer */
     111        memmove(conn->snd_buf, conn->snd_buf + data_size,
     112            conn->snd_buf_used - data_size);
     113        conn->snd_buf_used -= data_size;
     114
     115        tcp_tqueue_seg(conn, seg);
    64116}
    65117
  • uspace/srv/net/tl/tcp/tqueue.h

    r032bbe7 r32105348  
    4141extern void tcp_tqueue_ctrl_seg(tcp_conn_t *, tcp_control_t);
    4242extern void tcp_tqueue_seg(tcp_conn_t *, tcp_segment_t *);
     43extern void tcp_tqueue_new_data(tcp_conn_t *);
    4344extern void tcp_tqueue_remove_acked(tcp_conn_t *);
    4445extern void tcp_transmit_segment(tcp_sockpair_t *, tcp_segment_t *);
Note: See TracChangeset for help on using the changeset viewer.