Changeset 6df418c4 in mainline for uspace/srv/net/tl/tcp/tqueue.c


Ignore:
Timestamp:
2011-10-24T04:23:23Z (14 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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.