Quic deser retry

a fake deserializer for quic

object quic_deser_retry = {}

<<< member

    class `quic_deser_retry`;

>>>

<<< impl
    //TODO
define QUOTEME(x) QUOTEME_1(x) define QUOTEME_1(x) #x define QUIC_SER_DESER_HEADER_PATH PANTHER_IVY_BASE_DIR/quic_utils/quic_ser_deser.h include QUOTEME(QUIC_SER_DESER_HEADER_PATH)

    class `quic_deser_retry` : public ivy_binary_deser_128 {
    //class `quic_deser_retry` : public ivy_binary_deser {
        enum {quic_s_init,
              quic_s_type,
              quic_s_version,
              quic_s_dcil,
              quic_s_scil,
              quic_s_dcid,
              quic_s_scid,
              quic_s_retry_token,
              quic_s_retry_integrity_tag
            } state;
        bool long_format;
        char hdr_type;
        int dcil_long;
        int dcil;
        int scil;
        long frame_type;
        int data_remaining;
        int128_t ack_blocks_expected;
        int128_t ack_block_count;
        //long long ack_blocks_expected;
        //long long ack_block_count;
        int payload_length;
        int fence;
        bool have_scid = false;
        int token_count = 0;
        int tokeni_count = 0;
        int token_len;

    public:
        quic_deser_retry(const std::vector<char> &inp) : ivy_binary_deser_128(inp),state(quic_s_init) {
        //quic_deser_retry(const std::vector<char> &inp) : ivy_binary_deser(inp),state(quic_s_init) {
            // pos = 42; // skip 42 bytes of IP and UDP header
            fence = 0;
        }
        virtual void  get(int128_t &res) {
        //virtual void  get(long long &res) {
            switch (state) {
                case quic_s_init:
                {
                    getn(res,1);
                    long_format = (res & 0x80) ? true : false;
                    //0x7f is 0111 1111 in binary. This means the lower 7 bits of res are significant.
                    //0x30    0011 0000
                    hdr_type = res & 0x7f; //0x7f;
                    //This is then shifted by 4 so that only the original 0xxx 0000 (3) bits are significant.
                    res = long_format ? ((hdr_type & 0x30) >> 4) : 3;
                    state = quic_s_version;
                    std::cerr << "quic_s_init " << res << "\n";
                }
                break;
                case quic_s_version:
                {
                    if (long_format) {
                        ivy_binary_deser_128::getn(res,4);
                        //ivy_binary_deser::getn(res,4);
                    }
                    else
                        res = 0;
                    std::cerr << "quic_s_version " << res << "\n";
                    state = quic_s_dcid;
                }
                break;
                case quic_s_dcid:
                {
                    if (long_format) {
                        int128_t cil;
                        //long long cil;
                        getn(cil,1);
                        std::cerr << "dstID size " << cil << "\n";
                        dcil = cil;
                        dcid_h = cil;
                    } else {
                        dcil = dcid_h; //dcil_long
                    }
                    getn(res,dcil);
                    std::cerr << "dstID res " << res << "\n";
                    state = quic_s_scid;
                }
                break;
                case quic_s_scid:
                {
                    if (long_format) {
                        int128_t cil;
                        //long long cil;
                        getn(cil,1);
                        std::cerr << "sourceID size " << cil << "\n";
                        if(cil > 0)
                            have_scid = true;
                        else
                            have_scid = false;
                        scil = cil;
                        scid_h = cil;
                    } else {
                        scil = 0;
                    }
                    getn(res,scil);
                    std::cerr << "sourceID res " << res << "\n";
                    data_remaining = 8;
                    /*int128_t len;
                    //long long len;
                    if (long_format & ((hdr_type & 0x30) == 0x00)){
                        get_var_int(len);
                    }
                    else len = 0;
                    data_remaining = len;*/
                    std::cerr << "sourceID data_remaining " << data_remaining << "\n";
                    std::cerr << "scid " << res << "\n";
                    state = quic_s_retry_token;
                }
                break;
                case quic_s_retry_token:
                {
                    int packet_size = inp.size();
                    std::cerr << "packet_size " << packet_size << "\n";
                    int token_length = packet_size - 16 - 1 - dcil - 1 - scil - 1 - 4;
                    std::cerr << "token_length " << token_length << "\n";

                    char str_l[100];
                    sprintf(str_l,"%d",token_length);
                    if(setenv("RETRY_TOKEN_LENGTH",str_l,true) != 0)
                        fprintf(stderr, "setenv failed\n");

                    if(token_count == 0)
                        token_len = token_length;

                    std::cerr << "token_count " << token_count << "\n";

                    getn(res,1);
                    token_count += 1;
                    if(token_count == token_len)
                    state = quic_s_retry_integrity_tag;
                    else
                    state = quic_s_retry_token; //useless ?
                }
                break;
                case quic_s_retry_integrity_tag:
                {
                    std::cerr << "retry_integrity_tag inp " << inp.size() << "\n";
                    getn(res,16); //ivy_binary_deser_128::
                    /*if(tokeni_count < 16){
                        getn(res,1);
                        tokeni_count += 1;
                        state = quic_s_retry_integrity_tag;
                    }*/
                    //else */
                    token_count+=1;
                    std::cerr << "retry_integrity_tag " << res << "\n";
                }
                break;
                default:
                {
                    std::cerr << "quic_deser_retry 3\n";
                    throw deser_err();
                }
            }
        }

        void get_var_int(int128_t &res) {
        //void get_var_int(long long &res) {
            static int lens[4] = {0,1,3,7};
            int128_t lobyte;
            ivy_binary_deser_128::getn(lobyte,1);
            //long long lobyte;
            //ivy_binary_deser::getn(lobyte,1);
            int bytes = lens[(lobyte & 0xc0) >> 6];
            ivy_binary_deser_128::getn(res,bytes);
            //ivy_binary_deser::getn(res,bytes);
            res |= (lobyte & 0x3f) << (bytes << 3);
        }

        void get_pkt_num(int128_t &res) {
            ivy_binary_deser_128::getn(res,(hdr_type & 3)+1);
       // void get_pkt_num(long long &res) {
       //     ivy_binary_deser::getn(res,(hdr_type & 3)+1);
            return;
            static int lens[4] = {0,0,1,3};
            int128_t lobyte;
            ivy_binary_deser_128::getn(lobyte,1);
            //long long lobyte;
            //ivy_binary_deser::getn(lobyte,1);
            int bytes = lens[(lobyte & 0xc0) >> 6];
            if (bytes == 0) {
                res = lobyte;
                return;
            }
            ivy_binary_deser_128::getn(res,bytes);
            //ivy_binary_deser::getn(res,bytes);
            res |= (lobyte & 0x3f) << (bytes << 3);
        }

        virtual int open_tag(const std::vector<std::string> &tags) {
            std::cerr << "quic_deser_retry 6\n";
            throw deser_err();
        }

        virtual bool open_list_elem() {
            if (state == quic_s_retry_token) {
                // We must use/take in count the padding frame since Picoquic client sometimes send packet
                // only with 1 padding frame which make fails the requirement saying that a
                // packet cannot be empty
               /*while ((fence == 0 || pos < fence) && more(1) && inp[pos] == 0)
                   pos++;  // skip padding frames
                */
               return token_count < token_len; //(fence == 0 || pos < fence) && more(1);
            }
            if (quic_s_retry_integrity_tag) {
                // We must use/take in count the padding frame since Picoquic client sometimes send packet
                // only with 1 padding frame which make fails the requirement saying that a
                // packet cannot be empty
               /*while ((fence == 0 || pos < fence) && more(1) && inp[pos] == 0)
                   pos++;  // skip padding frames
                */
               return false; //more(16); //oken_count == token_len;//  (fence == 0 || pos < fence) && more(1); //more(1); //tokeni_count < 16; //more(16); //(fence == 0 || pos < fence) &&
            }
            if (state == quic_s_init)
                return more(1);
            std::cerr << "quic_deser_retry 1\n";
            throw deser_err();
        }

        void open_list() {

        }
        void close_list() {
            /*if (state == quic_s_retry_integrity_tag) {
                state = quic_s_init;
                pos += QUIC_DESER_FAKE_CHECKSUM_LENGTH; // skip the fake checksum
            }*/
            if (state == quic_s_retry_token) {
                state = quic_s_retry_integrity_tag;
            }
        }
        void close_list_elem() {}

        virtual void close_tag() {
            state = quic_s_retry_integrity_tag;
        }

        ~quic_deser_retry(){}
    };

>>>


<<< init

    transport_error_name_map(transport_error_codes,transport_error_codes_map);

>>>