Changeset 6df418c4 in mainline


Ignore:
Timestamp:
2011-10-24T04:23:23Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6e88fea
Parents:
f343a16
Message:

Retransmission queue, detect ACK of FIN.

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

Legend:

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

    rf343a16 r6df418c4  
    9999        tcp_iqueue_init(&conn->incoming, conn);
    100100
     101        /* Initialize retransmission queue */
     102        tcp_tqueue_init(&conn->retransmit, conn);
     103
    101104        conn->cstate = st_listen;
     105        conn->fin_is_acked = false;
    102106        conn->ident.local = *lsock;
    103107        if (fsock != NULL)
     
    152156                assert(false);
    153157        }
     158
     159        conn->fin_is_acked = false;
    154160}
    155161
     
    525531                return cp_done;
    526532
    527         /* TODO */
     533        if (conn->fin_is_acked) {
     534                log_msg(LVL_DEBUG, " FIN acked -> Fin-Wait-2");
     535                conn->cstate = st_fin_wait_2;
     536        }
     537
    528538        return cp_continue;
    529539}
  • uspace/srv/net/tl/tcp/conn.h

    rf343a16 r6df418c4  
    4343extern void tcp_conn_sync(tcp_conn_t *);
    4444extern void tcp_conn_fin_sent(tcp_conn_t *);
     45extern void tcp_conn_ack_of_fin_rcvd(tcp_conn_t *);
    4546extern tcp_conn_t *tcp_conn_find(tcp_sockpair_t *);
    4647extern bool tcp_conn_got_syn(tcp_conn_t *);
  • uspace/srv/net/tl/tcp/segment.c

    rf343a16 r6df418c4  
    5353}
    5454
     55/** Create duplicate of segment.
     56 *
     57 * @param seg   Segment
     58 * @return      Duplicate segment
     59 */
     60tcp_segment_t *tcp_segment_dup(tcp_segment_t *seg)
     61{
     62        tcp_segment_t *scopy;
     63        size_t tsize;
     64
     65        scopy = tcp_segment_new();
     66        if (scopy == NULL)
     67                return NULL;
     68
     69        scopy->ctrl = seg->ctrl;
     70        scopy->seq = seg->seq;
     71        scopy->ack = seg->ack;
     72        scopy->len = seg->len;
     73        scopy->wnd = seg->wnd;
     74        scopy->up = seg->up;
     75
     76        tsize = tcp_segment_text_size(seg);
     77        scopy->data = calloc(tsize, 1);
     78        if (scopy->data == NULL) {
     79                free(scopy);
     80                return NULL;
     81        }
     82
     83        memcpy(scopy->data, seg->data, tsize);
     84        scopy->dfptr = scopy->data;
     85
     86        return scopy;
     87}
     88
    5589/** Create a control-only segment.
    5690 *
  • uspace/srv/net/tl/tcp/segment.h

    rf343a16 r6df418c4  
    4141extern tcp_segment_t *tcp_segment_new(void);
    4242extern void tcp_segment_delete(tcp_segment_t *);
     43extern tcp_segment_t *tcp_segment_dup(tcp_segment_t *);
    4344extern tcp_segment_t *tcp_segment_make_ctrl(tcp_control_t);
    4445extern tcp_segment_t *tcp_segment_make_rst(tcp_segment_t *);
  • uspace/srv/net/tl/tcp/tcp_type.h

    rf343a16 r6df418c4  
    9999} tcp_iqueue_t;
    100100
     101typedef struct {
     102        struct tcp_conn *conn;
     103        list_t list;
     104} tcp_tqueue_t;
     105
    101106typedef struct tcp_conn {
    102107        link_t link;
     
    108113        tcp_cstate_t cstate;
    109114
     115        /** Set when FIN is removed from the retransmission queue */
     116        bool fin_is_acked;
     117
    110118        /** Queue of incoming segments */
    111119        tcp_iqueue_t incoming;
     120
     121        /** Retransmission queue */
     122        tcp_tqueue_t retransmit;
    112123
    113124        /** Receive buffer */
     
    199210} tcp_iqueue_entry_t;
    200211
     212typedef struct {
     213        link_t link;
     214        tcp_segment_t *seg;
     215} tcp_tqueue_entry_t;
     216
    201217typedef enum {
    202218        cp_continue,
  • uspace/srv/net/tl/tcp/tqueue.c

    rf343a16 r6df418c4  
    3535 */
    3636
     37#include <adt/list.h>
    3738#include <byteorder.h>
    3839#include <io/log.h>
    3940#include <macros.h>
    4041#include <mem.h>
     42#include <stdlib.h>
    4143#include "conn.h"
    4244#include "header.h"
    4345#include "rqueue.h"
    4446#include "segment.h"
     47#include "seq_no.h"
    4548#include "tqueue.h"
    4649#include "tcp_type.h"
    4750
     51void tcp_tqueue_init(tcp_tqueue_t *tqueue, tcp_conn_t *conn)
     52{
     53        tqueue->conn = conn;
     54        list_initialize(&tqueue->list);
     55}
     56
    4857void tcp_tqueue_ctrl_seg(tcp_conn_t *conn, tcp_control_t ctrl)
    4958{
     
    5867void tcp_tqueue_seg(tcp_conn_t *conn, tcp_segment_t *seg)
    5968{
     69        tcp_segment_t *rt_seg;
     70        tcp_tqueue_entry_t *tqe;
     71
    6072        log_msg(LVL_DEBUG, "tcp_tqueue_seg(%p, %p)", conn, seg);
    61         /* XXX queue */
     73
     74        /*
     75         * Add segment to retransmission queue
     76         */
     77
     78        if (seg->len > 0) {
     79                rt_seg = tcp_segment_dup(seg);
     80                if (rt_seg == NULL) {
     81                        log_msg(LVL_ERROR, "Memory allocation failed.");
     82                        /* XXX Handle properly */
     83                        return;
     84                }
     85
     86                tqe = calloc(1, sizeof(tcp_tqueue_entry_t));
     87                if (tqe == NULL) {
     88                        log_msg(LVL_ERROR, "Memory allocation failed.");
     89                        /* XXX Handle properly */
     90                        return;
     91                }
     92
     93                tqe->seg = rt_seg;
     94                list_append(&tqe->link, &conn->retransmit.list);
     95        }
    6296
    6397        /*
     
    146180void tcp_tqueue_ack_received(tcp_conn_t *conn)
    147181{
    148         (void) conn;
    149 
     182        link_t *cur, *next;
     183
     184        log_msg(LVL_DEBUG, "tcp_tqueue_ack_received(%p)", conn);
     185
     186        cur = conn->retransmit.list.head.next;
     187
     188        while (cur != &conn->retransmit.list.head) {
     189                next = cur->next;
     190
     191                tcp_tqueue_entry_t *tqe = list_get_instance(cur,
     192                    tcp_tqueue_entry_t, link);
     193
     194                if (seq_no_segment_acked(conn, tqe->seg, conn->snd_una)) {
     195                        /* Remove acknowledged segment */
     196                        list_remove(cur);
     197
     198                        if ((tqe->seg->ctrl & CTL_FIN) != 0) {
     199                                /* Our FIN has been acked */
     200                                conn->fin_is_acked = true;
     201                        }
     202
     203                        tcp_segment_delete(tqe->seg);
     204                        free(tqe);
     205                }
     206
     207                cur = next;
     208        }
     209
     210        /* Possibly transmit more data */
    150211        tcp_tqueue_new_data(conn);
    151212}
  • uspace/srv/net/tl/tcp/tqueue.h

    rf343a16 r6df418c4  
    3939#include "tcp_type.h"
    4040
     41extern void tcp_tqueue_init(tcp_tqueue_t *, tcp_conn_t *);
    4142extern void tcp_tqueue_ctrl_seg(tcp_conn_t *, tcp_control_t);
    4243extern void tcp_tqueue_seg(tcp_conn_t *, tcp_segment_t *);
Note: See TracChangeset for help on using the changeset viewer.