Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 975d528 in mainline


Ignore:
Timestamp:
2017-09-10T17:48:58Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
e1b4ae0
Parents:
12dcd5f
Message:

Add unit tests for TCP tqueue. Fix tqueue possibly being finalized without freeing pending segments.

Location:
uspace/srv/net/tcp
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tcp/Makefile

    r12dcd5f r975d528  
    6262        test/rqueue.c \
    6363        test/segment.c \
    64         test/seq_no.c
     64        test/seq_no.c \
     65        test/tqueue.c
    6566
    6667include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/tcp/conn.c

    r12dcd5f r975d528  
    4444#include <stdlib.h>
    4545#include "conn.h"
     46#include "inet.h"
    4647#include "iqueue.h"
     48#include "pdu.h"
    4749#include "segment.h"
    4850#include "seq_no.h"
     
    6264static amap_t *amap;
    6365
    64 static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg);
    65 static void tcp_conn_tw_timer_set(tcp_conn_t *conn);
    66 static void tcp_conn_tw_timer_clear(tcp_conn_t *conn);
     66static void tcp_conn_seg_process(tcp_conn_t *, tcp_segment_t *);
     67static void tcp_conn_tw_timer_set(tcp_conn_t *);
     68static void tcp_conn_tw_timer_clear(tcp_conn_t *);
     69static void tcp_transmit_segment(inet_ep2_t *, tcp_segment_t *);
     70
     71static tcp_tqueue_cb_t tcp_conn_tqueue_cb = {
     72        .transmit_seg = tcp_transmit_segment
     73};
    6774
    6875/** Initialize connections. */
     
    130137
    131138        /* Initialize retransmission queue */
    132         if (tcp_tqueue_init(&conn->retransmit, conn) != EOK)
     139        if (tcp_tqueue_init(&conn->retransmit, conn, &tcp_conn_tqueue_cb)
     140            != EOK) {
    133141                goto error;
     142        }
    134143
    135144        tqueue_inited = true;
     
    295304void tcp_conn_remove(tcp_conn_t *conn)
    296305{
     306        if (!link_used(&conn->link))
     307                return;
     308
    297309        fibril_mutex_lock(&conn_list_lock);
    298310        amap_remove(amap, &conn->ident);
     
    13461358}
    13471359
     1360static void tcp_transmit_segment(inet_ep2_t *epp, tcp_segment_t *seg)
     1361{
     1362        log_msg(LOG_DEFAULT, LVL_DEBUG,
     1363            "tcp_transmit_segment(l:(%u),f:(%u), %p)",
     1364            epp->local.port, epp->remote.port, seg);
     1365
     1366        log_msg(LOG_DEFAULT, LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
     1367            seg->seq, seg->wnd);
     1368
     1369        tcp_segment_dump(seg);
     1370
     1371//      tcp_rqueue_bounce_seg(sp, seg);
     1372//      tcp_ncsim_bounce_seg(sp, seg);
     1373
     1374        tcp_pdu_t *pdu;
     1375
     1376        if (tcp_pdu_encode(epp, seg, &pdu) != EOK) {
     1377                log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
     1378                return;
     1379        }
     1380
     1381        tcp_transmit_pdu(pdu);
     1382        tcp_pdu_delete(pdu);
     1383}
     1384
    13481385/** Compute flipped endpoint pair for response.
    13491386 *
  • uspace/srv/net/tcp/tcp_type.h

    r12dcd5f r975d528  
    126126} tcp_iqueue_t;
    127127
    128 /** Retransmission queue */
    129 typedef struct {
    130         struct tcp_conn *conn;
    131         list_t list;
    132 
    133         /** Retransmission timer */
    134         fibril_timer_t *timer;
    135 } tcp_tqueue_t;
    136 
    137128/** Active or passive connection */
    138129typedef enum {
     
    156147        void (*recv_data)(tcp_conn_t *, void *);
    157148} tcp_cb_t;
     149
     150/** Data returned by Status user call */
     151typedef struct {
     152        /** Connection state */
     153        tcp_cstate_t cstate;
     154} tcp_conn_status_t;
     155
     156typedef struct {
     157        /** SYN, FIN */
     158        tcp_control_t ctrl;
     159
     160        /** Segment sequence number */
     161        uint32_t seq;
     162        /** Segment acknowledgement number */
     163        uint32_t ack;
     164        /** Segment length in sequence space */
     165        uint32_t len;
     166        /** Segment window */
     167        uint32_t wnd;
     168        /** Segment urgent pointer */
     169        uint32_t up;
     170
     171        /** Segment data, may be moved when trimming segment */
     172        void *data;
     173        /** Segment data, original pointer used to free data */
     174        void *dfptr;
     175} tcp_segment_t;
     176
     177/** Receive queue entry */
     178typedef struct {
     179        link_t link;
     180        inet_ep2_t epp;
     181        tcp_segment_t *seg;
     182} tcp_rqueue_entry_t;
     183
     184/** Receive queue callbacks */
     185typedef struct {
     186        /** Segment received */
     187        void (*seg_received)(inet_ep2_t *, tcp_segment_t *);
     188} tcp_rqueue_cb_t;
     189
     190/** NCSim queue entry */
     191typedef struct {
     192        link_t link;
     193        suseconds_t delay;
     194        inet_ep2_t epp;
     195        tcp_segment_t *seg;
     196} tcp_squeue_entry_t;
     197
     198/** Incoming queue entry */
     199typedef struct {
     200        link_t link;
     201        tcp_segment_t *seg;
     202} tcp_iqueue_entry_t;
     203
     204/** Retransmission queue entry */
     205typedef struct {
     206        link_t link;
     207        tcp_conn_t *conn;
     208        tcp_segment_t *seg;
     209} tcp_tqueue_entry_t;
     210
     211/** Retransmission queue callbacks */
     212typedef struct {
     213        /** Segment received */
     214        void (*transmit_seg)(inet_ep2_t *, tcp_segment_t *);
     215} tcp_tqueue_cb_t;
     216
     217/** Retransmission queue */
     218typedef struct {
     219        struct tcp_conn *conn;
     220        list_t list;
     221
     222        /** Retransmission timer */
     223        fibril_timer_t *timer;
     224
     225        /** Callbacks */
     226        tcp_tqueue_cb_t *cb;
     227} tcp_tqueue_t;
    158228
    159229/** Connection */
     
    246316};
    247317
    248 /** Data returned by Status user call */
    249 typedef struct {
    250         /** Connection state */
    251         tcp_cstate_t cstate;
    252 } tcp_conn_status_t;
    253 
    254 typedef struct {
    255         /** SYN, FIN */
    256         tcp_control_t ctrl;
    257 
    258         /** Segment sequence number */
    259         uint32_t seq;
    260         /** Segment acknowledgement number */
    261         uint32_t ack;
    262         /** Segment length in sequence space */
    263         uint32_t len;
    264         /** Segment window */
    265         uint32_t wnd;
    266         /** Segment urgent pointer */
    267         uint32_t up;
    268 
    269         /** Segment data, may be moved when trimming segment */
    270         void *data;
    271         /** Segment data, original pointer used to free data */
    272         void *dfptr;
    273 } tcp_segment_t;
    274 
    275 /** Receive queue entry */
    276 typedef struct {
    277         link_t link;
    278         inet_ep2_t epp;
    279         tcp_segment_t *seg;
    280 } tcp_rqueue_entry_t;
    281 
    282 /** Receive queue callbacks */
    283 typedef struct {
    284         /** Segment received */
    285         void (*seg_received)(inet_ep2_t *, tcp_segment_t *);
    286 } tcp_rqueue_cb_t;
    287 
    288 /** NCSim queue entry */
    289 typedef struct {
    290         link_t link;
    291         suseconds_t delay;
    292         inet_ep2_t epp;
    293         tcp_segment_t *seg;
    294 } tcp_squeue_entry_t;
    295 
    296 /** Incoming queue entry */
    297 typedef struct {
    298         link_t link;
    299         tcp_segment_t *seg;
    300 } tcp_iqueue_entry_t;
    301 
    302 /** Retransmission queue entry */
    303 typedef struct {
    304         link_t link;
    305         tcp_conn_t *conn;
    306         tcp_segment_t *seg;
    307 } tcp_tqueue_entry_t;
    308 
    309318/** Continuation of processing.
    310319 *
  • uspace/srv/net/tcp/test/main.c

    r12dcd5f r975d528  
    6262PCUT_IMPORT(segment);
    6363PCUT_IMPORT(seq_no);
     64PCUT_IMPORT(tqueue);
    6465
    6566PCUT_MAIN()
  • uspace/srv/net/tcp/tqueue.c

    r12dcd5f r975d528  
    4747#include "inet.h"
    4848#include "ncsim.h"
    49 #include "pdu.h"
    5049#include "rqueue.h"
    5150#include "segment.h"
     
    5655#define RETRANSMIT_TIMEOUT      (2*1000*1000)
    5756
    58 static void retransmit_timeout_func(void *arg);
    59 static void tcp_tqueue_timer_set(tcp_conn_t *conn);
    60 static void tcp_tqueue_timer_clear(tcp_conn_t *conn);
    61 
    62 int tcp_tqueue_init(tcp_tqueue_t *tqueue, tcp_conn_t *conn)
     57static void retransmit_timeout_func(void *);
     58static void tcp_tqueue_timer_set(tcp_conn_t *);
     59static void tcp_tqueue_timer_clear(tcp_conn_t *);
     60static void tcp_tqueue_seg(tcp_conn_t *, tcp_segment_t *);
     61static void tcp_conn_transmit_segment(tcp_conn_t *, tcp_segment_t *);
     62static void tcp_prepare_transmit_segment(tcp_conn_t *, tcp_segment_t *);
     63static void tcp_tqueue_send_immed(tcp_conn_t *, tcp_segment_t *);
     64
     65int tcp_tqueue_init(tcp_tqueue_t *tqueue, tcp_conn_t *conn,
     66    tcp_tqueue_cb_t *cb)
    6367{
    6468        tqueue->conn = conn;
    6569        tqueue->timer = fibril_timer_create(&conn->lock);
     70        tqueue->cb = cb;
    6671        if (tqueue->timer == NULL)
    6772                return ENOMEM;
     
    7984void tcp_tqueue_fini(tcp_tqueue_t *tqueue)
    8085{
     86        link_t *link;
     87        tcp_tqueue_entry_t *tqe;
     88
    8189        if (tqueue->timer != NULL) {
    8290                fibril_timer_destroy(tqueue->timer);
    8391                tqueue->timer = NULL;
    8492        }
     93
     94        while (!list_empty(&tqueue->list)) {
     95                link = list_first(&tqueue->list);
     96                tqe = list_get_instance(link, tcp_tqueue_entry_t, link);
     97                list_remove(link);
     98
     99                tcp_segment_delete(tqe->seg);
     100                free(tqe);
     101        }
    85102}
    86103
     
    96113}
    97114
    98 void tcp_tqueue_seg(tcp_conn_t *conn, tcp_segment_t *seg)
     115static void tcp_tqueue_seg(tcp_conn_t *conn, tcp_segment_t *seg)
    99116{
    100117        tcp_segment_t *rt_seg;
     
    136153}
    137154
    138 void tcp_prepare_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg)
     155static void tcp_prepare_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg)
    139156{
    140157        /*
     
    268285}
    269286
    270 void tcp_conn_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg)
     287static void tcp_conn_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg)
    271288{
    272289        log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_transmit_segment(%p, %p)",
     
    280297                seg->ack = 0;
    281298
    282         tcp_transmit_segment(&conn->ident, seg);
    283 }
    284 
    285 void tcp_transmit_segment(inet_ep2_t *epp, tcp_segment_t *seg)
     299        tcp_tqueue_send_immed(conn, seg);
     300}
     301
     302void tcp_tqueue_send_immed(tcp_conn_t *conn, tcp_segment_t *seg)
    286303{
    287304        log_msg(LOG_DEFAULT, LVL_DEBUG,
    288             "tcp_transmit_segment(l:(%u),f:(%u), %p)",
    289             epp->local.port, epp->remote.port, seg);
     305            "tcp_tqueue_send_immed(l:(%u),f:(%u), %p)",
     306            conn->ident.local.port, conn->ident.remote.port, seg);
    290307
    291308        log_msg(LOG_DEFAULT, LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
     
    293310
    294311        tcp_segment_dump(seg);
    295 /*
    296         tcp_pdu_prepare(conn, seg, &data, &len);
    297         tcp_pdu_transmit(data, len);
    298 */
    299 //      tcp_rqueue_bounce_seg(sp, seg);
    300 //      tcp_ncsim_bounce_seg(sp, seg);
    301 
    302         tcp_pdu_t *pdu;
    303 
    304         if (tcp_pdu_encode(epp, seg, &pdu) != EOK) {
    305                 log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
    306                 return;
    307         }
    308 
    309         tcp_transmit_pdu(pdu);
    310         tcp_pdu_delete(pdu);
     312
     313        conn->retransmit.cb->transmit_seg(&conn->ident, seg);
    311314}
    312315
  • uspace/srv/net/tcp/tqueue.h

    r12dcd5f r975d528  
    4040#include "tcp_type.h"
    4141
    42 extern int tcp_tqueue_init(tcp_tqueue_t *, tcp_conn_t *);
     42extern int tcp_tqueue_init(tcp_tqueue_t *, tcp_conn_t *,
     43    tcp_tqueue_cb_t *);
    4344extern void tcp_tqueue_clear(tcp_tqueue_t *);
    4445extern void tcp_tqueue_fini(tcp_tqueue_t *);
    4546extern void tcp_tqueue_ctrl_seg(tcp_conn_t *, tcp_control_t);
    46 extern void tcp_tqueue_seg(tcp_conn_t *, tcp_segment_t *);
    4747extern void tcp_tqueue_new_data(tcp_conn_t *);
    4848extern void tcp_tqueue_ack_received(tcp_conn_t *);
    49 extern void tcp_prepare_transmit_segment(tcp_conn_t *, tcp_segment_t *);
    50 extern void tcp_conn_transmit_segment(tcp_conn_t *, tcp_segment_t *);
    51 extern void tcp_transmit_segment(inet_ep2_t *, tcp_segment_t *);
    52 extern void tcp_header_setup(tcp_conn_t *, tcp_segment_t *, tcp_header_t *);
    53 extern void tcp_phdr_setup(tcp_conn_t *, tcp_segment_t *, tcp_phdr_t *);
    5449
    5550#endif
Note: See TracChangeset for help on using the changeset viewer.