1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
25f5d395bSDmitri Tikhonov/*
35f5d395bSDmitri Tikhonov * Test the "nocopy" data in stream
45f5d395bSDmitri Tikhonov */
55f5d395bSDmitri Tikhonov
65f5d395bSDmitri Tikhonov#include <assert.h>
75f5d395bSDmitri Tikhonov#include <stdio.h>
85f5d395bSDmitri Tikhonov#include <string.h>
95f5d395bSDmitri Tikhonov#include <sys/queue.h>
102d296031SDmitri Tikhonov#ifdef WIN32
112d296031SDmitri Tikhonov#include "getopt.h"
122d296031SDmitri Tikhonov#else
135f5d395bSDmitri Tikhonov#include <unistd.h>
142d296031SDmitri Tikhonov#endif
155f5d395bSDmitri Tikhonov
165f5d395bSDmitri Tikhonov#include "lsquic.h"
175f5d395bSDmitri Tikhonov#include "lsquic_int_types.h"
185f5d395bSDmitri Tikhonov#include "lsquic_sfcw.h"
195f5d395bSDmitri Tikhonov#include "lsquic_rtt.h"
205f5d395bSDmitri Tikhonov#include "lsquic_conn_flow.h"
215392f7a3SLiteSpeed Tech#include "lsquic_varint.h"
225392f7a3SLiteSpeed Tech#include "lsquic_hq.h"
235392f7a3SLiteSpeed Tech#include "lsquic_hash.h"
245f5d395bSDmitri Tikhonov#include "lsquic_stream.h"
255f5d395bSDmitri Tikhonov#include "lsquic_conn.h"
265f5d395bSDmitri Tikhonov#include "lsquic_conn_public.h"
275f5d395bSDmitri Tikhonov#include "lsquic_malo.h"
285f5d395bSDmitri Tikhonov#include "lsquic_packet_common.h"
295f5d395bSDmitri Tikhonov#include "lsquic_packet_in.h"
305f5d395bSDmitri Tikhonov#include "lsquic_packet_out.h"
315f5d395bSDmitri Tikhonov#include "lsquic_mm.h"
325f5d395bSDmitri Tikhonov#include "lsquic_logger.h"
335f5d395bSDmitri Tikhonov#include "lsquic_data_in_if.h"
345f5d395bSDmitri Tikhonov
355f5d395bSDmitri Tikhonov
365f5d395bSDmitri Tikhonovstruct nocopy_test
375f5d395bSDmitri Tikhonov{
385f5d395bSDmitri Tikhonov    int     lineno;
395f5d395bSDmitri Tikhonov
405f5d395bSDmitri Tikhonov    /* Setup: initial set of frames to insert and read until some offset */
415f5d395bSDmitri Tikhonov    unsigned            n_init_frames;
425f5d395bSDmitri Tikhonov    struct data_frame   initial_frames[5];
435f5d395bSDmitri Tikhonov    unsigned            read_until;
445f5d395bSDmitri Tikhonov
455f5d395bSDmitri Tikhonov    /* Test: data frame to insert and expected insert result */
465f5d395bSDmitri Tikhonov    struct data_frame   data_frame;
475f5d395bSDmitri Tikhonov    enum ins_frame      ins;
485f5d395bSDmitri Tikhonov};
495f5d395bSDmitri Tikhonov
505f5d395bSDmitri Tikhonov
515f5d395bSDmitri Tikhonov#define F(off, size, fin) { .df_offset = (off), .df_fin = (fin), .df_size = (size), }
525f5d395bSDmitri Tikhonov
535f5d395bSDmitri Tikhonovstatic const struct nocopy_test tests[] =
545f5d395bSDmitri Tikhonov{
555f5d395bSDmitri Tikhonov
565f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
575f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
585f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 300, 0), },
595f5d395bSDmitri Tikhonov        .read_until     = 300,
605f5d395bSDmitri Tikhonov        .data_frame     = F(200, 100, 0),
615f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_DUP,
625f5d395bSDmitri Tikhonov    },
635f5d395bSDmitri Tikhonov
645f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
655f5d395bSDmitri Tikhonov        .n_init_frames  = 2,
665f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 300, 0), F(300, 100, 0), },
675f5d395bSDmitri Tikhonov        .read_until     = 300,
685f5d395bSDmitri Tikhonov        .data_frame     = F(200, 100, 0),
695f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_DUP,
705f5d395bSDmitri Tikhonov    },
715f5d395bSDmitri Tikhonov
725f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
735f5d395bSDmitri Tikhonov        .n_init_frames  = 2,
745f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 300, 0), F(300, 0, 1), },
755f5d395bSDmitri Tikhonov        .read_until     = 300,
765f5d395bSDmitri Tikhonov        .data_frame     = F(200, 100, 1),
775f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_DUP,
785f5d395bSDmitri Tikhonov    },
795f5d395bSDmitri Tikhonov
805f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
815f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
825f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 301, 0), },
835f5d395bSDmitri Tikhonov        .read_until     = 301,
845f5d395bSDmitri Tikhonov        .data_frame     = F(200, 100, 1),
855f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_ERR,
865f5d395bSDmitri Tikhonov    },
875f5d395bSDmitri Tikhonov
885f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
895f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
905f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 400, 0), },
915f5d395bSDmitri Tikhonov        .read_until     = 301,
925f5d395bSDmitri Tikhonov        .data_frame     = F(200, 100, 0),
935f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_DUP,
945f5d395bSDmitri Tikhonov    },
955f5d395bSDmitri Tikhonov
965f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
975f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
985f5d395bSDmitri Tikhonov        .initial_frames = { F(200, 100, 1), },
995f5d395bSDmitri Tikhonov        .read_until     = 0,
1005f5d395bSDmitri Tikhonov        .data_frame     = F(200, 50, 1),
1015f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_ERR,
1025f5d395bSDmitri Tikhonov    },
1035f5d395bSDmitri Tikhonov
1045f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1055f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1065f5d395bSDmitri Tikhonov        .initial_frames = { F(200, 100, 1), },
1075f5d395bSDmitri Tikhonov        .read_until     = 0,
1085f5d395bSDmitri Tikhonov        .data_frame     = F(200, 150, 1),
1095f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_ERR,
1105f5d395bSDmitri Tikhonov    },
1115f5d395bSDmitri Tikhonov
1125f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1135f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1145f5d395bSDmitri Tikhonov        .initial_frames = { F(200, 100, 1), },
1155f5d395bSDmitri Tikhonov        .read_until     = 0,
1165f5d395bSDmitri Tikhonov        .data_frame     = F(200, 101, 0),
1175f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_ERR,
1185f5d395bSDmitri Tikhonov    },
1195f5d395bSDmitri Tikhonov
1205f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1215f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1225f5d395bSDmitri Tikhonov        .initial_frames = { F(200, 100, 1), },
1235f5d395bSDmitri Tikhonov        .read_until     = 0,
1245f5d395bSDmitri Tikhonov        .data_frame     = F(500, 1, 0),
1255f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_ERR,
1265f5d395bSDmitri Tikhonov    },
1275f5d395bSDmitri Tikhonov
1285f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1295f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1305f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 0), },
1315f5d395bSDmitri Tikhonov        .read_until     = 100,
1325f5d395bSDmitri Tikhonov        .data_frame     = F(0, 100, 1),
1335f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_OVERLAP,
1345f5d395bSDmitri Tikhonov    },
1355f5d395bSDmitri Tikhonov
1365f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1375f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1385f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 1), },
1395f5d395bSDmitri Tikhonov        .read_until     = 100,
1405f5d395bSDmitri Tikhonov        .data_frame     = F(0, 100, 1),
1415f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_DUP,
1425f5d395bSDmitri Tikhonov    },
1435f5d395bSDmitri Tikhonov
1445f5d395bSDmitri Tikhonov    /* TODO: Case 'F' and 'L' -- remove "case 'F'" */
1455f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1465f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1475f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 0), },
1485f5d395bSDmitri Tikhonov        .read_until     = 100,
1495f5d395bSDmitri Tikhonov        .data_frame     = F(0, 100, 0),
1505f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_DUP,
1515f5d395bSDmitri Tikhonov    },
1525f5d395bSDmitri Tikhonov
1535f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1545f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1555f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 1), },
1565f5d395bSDmitri Tikhonov        .read_until     = 10,
1575f5d395bSDmitri Tikhonov        .data_frame     = F(0, 100, 0),
1585f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_DUP,
1595f5d395bSDmitri Tikhonov    },
1605f5d395bSDmitri Tikhonov
1615f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1625f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1635f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 0), },
1645f5d395bSDmitri Tikhonov        .read_until     = 10,
1655f5d395bSDmitri Tikhonov        .data_frame     = F(0, 100, 1),
1665f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_OVERLAP,
1675f5d395bSDmitri Tikhonov    },
1685f5d395bSDmitri Tikhonov
1695f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1705f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1715f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 0), },
1725f5d395bSDmitri Tikhonov        .read_until     = 100,
1735f5d395bSDmitri Tikhonov        .data_frame     = F(100, 0, 0),
1745f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_DUP,
1755f5d395bSDmitri Tikhonov    },
1765f5d395bSDmitri Tikhonov
1775f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1785f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1795f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 0), },
1805f5d395bSDmitri Tikhonov        .read_until     = 0,
1815f5d395bSDmitri Tikhonov        .data_frame     = F(50, 100, 0),
1825f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_OVERLAP,
1835f5d395bSDmitri Tikhonov    },
1845f5d395bSDmitri Tikhonov
1855f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1865f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1875f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 1), },
1885f5d395bSDmitri Tikhonov        .read_until     = 0,
1895f5d395bSDmitri Tikhonov        .data_frame     = F(50, 100, 0),
1905f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_ERR,
1915f5d395bSDmitri Tikhonov    },
1925f5d395bSDmitri Tikhonov
1935f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
1945f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
1955f5d395bSDmitri Tikhonov        .initial_frames = { F(100, 100, 0), },
1965f5d395bSDmitri Tikhonov        .read_until     = 0,
1975f5d395bSDmitri Tikhonov        .data_frame     = F(50, 100, 0),
1985f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_OVERLAP,
1995f5d395bSDmitri Tikhonov    },
2005f5d395bSDmitri Tikhonov
2015f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
2025f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
2035f5d395bSDmitri Tikhonov        .initial_frames = { F(100, 100, 0), },
2045f5d395bSDmitri Tikhonov        .read_until     = 0,
2055f5d395bSDmitri Tikhonov        .data_frame     = F(50, 100, 1),
2065f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_OVERLAP,    /* This is really an error,
2075f5d395bSDmitri Tikhonov                                                 * but we ignore it.
2085f5d395bSDmitri Tikhonov                                                 */
2095f5d395bSDmitri Tikhonov    },
2105f5d395bSDmitri Tikhonov
2115f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
2125f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
2135f5d395bSDmitri Tikhonov        .initial_frames = { F(100, 100, 1), },
2145f5d395bSDmitri Tikhonov        .read_until     = 0,
2155f5d395bSDmitri Tikhonov        .data_frame     = F(50, 100, 0),
2165f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_OVERLAP,
2175f5d395bSDmitri Tikhonov    },
2185f5d395bSDmitri Tikhonov
2195f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
2205f5d395bSDmitri Tikhonov        .n_init_frames  = 1,
2215f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 1), },
2225f5d395bSDmitri Tikhonov        .read_until     = 60,
2235f5d395bSDmitri Tikhonov        .data_frame     = F(50, 2, 0),
2245f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_DUP,
2255f5d395bSDmitri Tikhonov    },
2265f5d395bSDmitri Tikhonov
2275f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
2285f5d395bSDmitri Tikhonov        .n_init_frames  = 2,
2295f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 0), F(200, 100, 0), },
2305f5d395bSDmitri Tikhonov        .read_until     = 0,
2315f5d395bSDmitri Tikhonov        .data_frame     = F(50, 200, 0),
2325f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_OVERLAP,
2335f5d395bSDmitri Tikhonov    },
2345f5d395bSDmitri Tikhonov
2355f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
2365f5d395bSDmitri Tikhonov        .n_init_frames  = 2,
2375f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 0), F(200, 100, 0), },
2385f5d395bSDmitri Tikhonov        .read_until     = 0,
2395f5d395bSDmitri Tikhonov        .data_frame     = F(100, 100, 0),
2405f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_OK,
2415f5d395bSDmitri Tikhonov    },
2425f5d395bSDmitri Tikhonov
2435f5d395bSDmitri Tikhonov    {   .lineno         = __LINE__,
2445f5d395bSDmitri Tikhonov        .n_init_frames  = 2,
2455f5d395bSDmitri Tikhonov        .initial_frames = { F(0, 100, 0), F(200, 100, 0), },
2465f5d395bSDmitri Tikhonov        .read_until     = 0,
2475f5d395bSDmitri Tikhonov        .data_frame     = F(100, 100, 1),
2485f5d395bSDmitri Tikhonov        .ins            = INS_FRAME_OK,     /* Ignore another error */
2495f5d395bSDmitri Tikhonov    },
2505f5d395bSDmitri Tikhonov
2515392f7a3SLiteSpeed Tech    {   .lineno         = __LINE__,
2525392f7a3SLiteSpeed Tech        .n_init_frames  = 2,
2535392f7a3SLiteSpeed Tech        .initial_frames = { F(0, 60, 0), F(60, 60, 0), },
2545392f7a3SLiteSpeed Tech        .read_until     = 120,
2555392f7a3SLiteSpeed Tech        .data_frame     = F(0, 180, 0),
2565392f7a3SLiteSpeed Tech        .ins            = INS_FRAME_OVERLAP,
2575392f7a3SLiteSpeed Tech    },
2585392f7a3SLiteSpeed Tech
2595392f7a3SLiteSpeed Tech    {   .lineno         = __LINE__,
2605392f7a3SLiteSpeed Tech        .n_init_frames  = 3,
2615392f7a3SLiteSpeed Tech        .initial_frames = { F(0, 60, 0), F(60, 60, 0), F(180, 60, 0), },
2625392f7a3SLiteSpeed Tech        .read_until     = 120,
2635392f7a3SLiteSpeed Tech        .data_frame     = F(0, 180, 0),
2645392f7a3SLiteSpeed Tech        .ins            = INS_FRAME_OVERLAP,
2655392f7a3SLiteSpeed Tech    },
2665392f7a3SLiteSpeed Tech
2675f5d395bSDmitri Tikhonov};
2685f5d395bSDmitri Tikhonov
2695f5d395bSDmitri Tikhonov
2705f5d395bSDmitri Tikhonovstatic void
2715f5d395bSDmitri Tikhonovrun_di_nocopy_test (const struct nocopy_test *test)
2725f5d395bSDmitri Tikhonov{
2735f5d395bSDmitri Tikhonov    struct lsquic_mm mm;
2745f5d395bSDmitri Tikhonov    struct lsquic_conn_public conn_pub;
2755f5d395bSDmitri Tikhonov    struct lsquic_conn conn;
2765f5d395bSDmitri Tikhonov    struct stream_frame *frame;
2775f5d395bSDmitri Tikhonov    struct data_in *di;
2785f5d395bSDmitri Tikhonov    struct data_frame *data_frame;
2795f5d395bSDmitri Tikhonov    enum ins_frame ins;
2805f5d395bSDmitri Tikhonov    unsigned i;
2815f5d395bSDmitri Tikhonov    unsigned nread, n_to_read;
2825f5d395bSDmitri Tikhonov
2835f5d395bSDmitri Tikhonov    LSQ_NOTICE("running test on line %d", test->lineno);
2845f5d395bSDmitri Tikhonov
2855f5d395bSDmitri Tikhonov    lsquic_mm_init(&mm);
2865f5d395bSDmitri Tikhonov    memset(&conn, 0, sizeof(conn));
2875f5d395bSDmitri Tikhonov    conn_pub.lconn = &conn;
2885f5d395bSDmitri Tikhonov    conn_pub.mm = &mm;
2895f5d395bSDmitri Tikhonov
290a5fa05f9SDmitri Tikhonov    di = lsquic_data_in_nocopy_new(&conn_pub, 3);
2915f5d395bSDmitri Tikhonov
2925f5d395bSDmitri Tikhonov    for (i = 0; i < test->n_init_frames; ++i)
2935f5d395bSDmitri Tikhonov    {
2945f5d395bSDmitri Tikhonov        frame = lsquic_malo_get(mm.malo.stream_frame);
2955f5d395bSDmitri Tikhonov        frame->packet_in = lsquic_mm_get_packet_in(&mm);
2965f5d395bSDmitri Tikhonov        frame->packet_in->pi_refcnt = 1;
2975f5d395bSDmitri Tikhonov        frame->data_frame = test->initial_frames[i];
2985f5d395bSDmitri Tikhonov        ins = di->di_if->di_insert_frame(di, frame, 0);
2995f5d395bSDmitri Tikhonov        assert(INS_FRAME_OK == ins);    /* Self-test */
3005f5d395bSDmitri Tikhonov    }
3015f5d395bSDmitri Tikhonov
3025f5d395bSDmitri Tikhonov    nread = 0;
3035f5d395bSDmitri Tikhonov    while (nread < test->read_until)
3045f5d395bSDmitri Tikhonov    {
3055f5d395bSDmitri Tikhonov        data_frame = di->di_if->di_get_frame(di, nread);
3065f5d395bSDmitri Tikhonov        assert(data_frame);  /* Self-check */
3076f126d80SDmitri Tikhonov        n_to_read = test->read_until - nread > (unsigned) data_frame->df_size - data_frame->df_read_off
3086f126d80SDmitri Tikhonov                            ? (unsigned) data_frame->df_size - data_frame->df_read_off : test->read_until - nread;
3095f5d395bSDmitri Tikhonov        data_frame->df_read_off += n_to_read;
3105f5d395bSDmitri Tikhonov        nread += n_to_read;
3115f5d395bSDmitri Tikhonov        if (data_frame->df_read_off == data_frame->df_size)
3125f5d395bSDmitri Tikhonov            di->di_if->di_frame_done(di, data_frame);
3135f5d395bSDmitri Tikhonov        else
3145f5d395bSDmitri Tikhonov        {
3155f5d395bSDmitri Tikhonov            assert(nread == test->read_until);
3165f5d395bSDmitri Tikhonov            break;
3175f5d395bSDmitri Tikhonov        }
3185f5d395bSDmitri Tikhonov    }
3195f5d395bSDmitri Tikhonov
3205f5d395bSDmitri Tikhonov    frame = lsquic_malo_get(mm.malo.stream_frame);
3215f5d395bSDmitri Tikhonov    frame->packet_in = lsquic_mm_get_packet_in(&mm);
3225f5d395bSDmitri Tikhonov    frame->packet_in->pi_refcnt = 1;
3235f5d395bSDmitri Tikhonov    frame->data_frame = test->data_frame;
3245f5d395bSDmitri Tikhonov    ins = di->di_if->di_insert_frame(di, frame, test->read_until);
3255f5d395bSDmitri Tikhonov    assert(test->ins == ins);
3265f5d395bSDmitri Tikhonov
3275f5d395bSDmitri Tikhonov    di->di_if->di_destroy(di);
3285f5d395bSDmitri Tikhonov    lsquic_mm_cleanup(&mm);
3295f5d395bSDmitri Tikhonov}
3305f5d395bSDmitri Tikhonov
3315f5d395bSDmitri Tikhonov
3325f5d395bSDmitri Tikhonovint
3335f5d395bSDmitri Tikhonovmain (int argc, char **argv)
3345f5d395bSDmitri Tikhonov{
3355f5d395bSDmitri Tikhonov    const struct nocopy_test *test;
3365f5d395bSDmitri Tikhonov    int opt;
3375f5d395bSDmitri Tikhonov
3385f5d395bSDmitri Tikhonov    lsquic_log_to_fstream(stderr, LLTS_NONE);
3395f5d395bSDmitri Tikhonov
3405f5d395bSDmitri Tikhonov    while (-1 != (opt = getopt(argc, argv, "l:")))
3415f5d395bSDmitri Tikhonov    {
3425f5d395bSDmitri Tikhonov        switch (opt)
3435f5d395bSDmitri Tikhonov        {
3445f5d395bSDmitri Tikhonov        case 'l':
3455f5d395bSDmitri Tikhonov            lsquic_logger_lopt(optarg);
3465f5d395bSDmitri Tikhonov            break;
3475f5d395bSDmitri Tikhonov        default:
3485f5d395bSDmitri Tikhonov            return 1;
3495f5d395bSDmitri Tikhonov        }
3505f5d395bSDmitri Tikhonov    }
3515f5d395bSDmitri Tikhonov
3525f5d395bSDmitri Tikhonov    for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test)
3535f5d395bSDmitri Tikhonov        run_di_nocopy_test(test);
3545f5d395bSDmitri Tikhonov
3555f5d395bSDmitri Tikhonov    return 0;
3565f5d395bSDmitri Tikhonov}
357