Quic deser retry
a fake deserializer for quic
object quic_deser_retry = {}
<<< member
class `quic_deser_retry`;
>>>
<<< impl
//TODO
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);
>>>