rohc team mailing list archive
-
rohc team
-
Mailing list archive
-
Message #01729
IP-ID handling in the ROHC TCP profile (Was: Re: rohc-lib 1.7.0 - problem with new return values (rohc_status_t) and lost tcp packets)
Hi Sean,
> > Any progress on the IP-ID patch?
> >
> > I now have time to spend testing if you would like.
>
> I didn't have time to look at it again. I'll retrieve the patch this
> weekend and send it to you so you can test it in its current state.
I re-worked the IP-ID patch to make it work again with the main branch.
It builds fine on x86 and all non-regression tests run fine too.
Tell me if it improves the situation for you.
Regards,
Didier
=== modified file 'src/comp/c_tcp.c'
--- src/comp/c_tcp.c 2014-06-23 21:17:33 +0000
+++ src/comp/c_tcp.c 2014-07-20 09:48:03 +0000
@@ -137,11 +137,12 @@ struct tcp_tmp_variables
size_t nr_opt_ts_reply_bits_0x40000;
uint16_t ip_id;
+ uint16_t ip_id_offset;
bool ip_id_behavior_changed;
- bool ip_id_hi9_changed; /* TODO: replace by the number of required bits */
- bool ip_id_hi11_changed; /* TODO: replace by the number of required bits */
- bool ip_id_hi12_changed; /* TODO: replace by the number of required bits */
- bool ip_id_hi13_changed; /* TODO: replace by the number of required bits */
+ /** The minimal number of bits required to encode the IP-ID with p = 1 */
+ size_t nr_ipid_bits_1;
+ /** The minimal number of bits required to encode the IP-ID with p = 3 */
+ size_t nr_ipid_bits_3;
uint8_t ttl_hopl;
int ttl_irregular_chain_flag;
@@ -411,6 +412,8 @@ struct sc_tcp_context
/// compression of packet
struct tcp_tmp_variables tmp;
+ struct c_wlsb *ipid_wlsb;
+
uint8_t ip_context[1];
};
@@ -984,6 +987,16 @@ static bool c_tcp_create(struct rohc_com
memcpy(&(tcp_context->old_tcphdr), tcp, sizeof(tcphdr_t));
+ /* IP-ID offset */
+ tcp_context->ipid_wlsb =
+ c_create_wlsb(16, comp->wlsb_window_width, ROHC_LSB_SHIFT_VAR);
+ if(tcp_context->ipid_wlsb == NULL)
+ {
+ rohc_error(context->compressor, ROHC_TRACE_COMP, context->profile->id,
+ "failed to create W-LSB context for IP-ID offset");
+ goto free_context;
+ }
+
/* TCP sequence number */
tcp_context->seq_num = rohc_ntoh32(tcp->seq_num);
tcp_context->seq_wlsb =
@@ -992,7 +1005,7 @@ static bool c_tcp_create(struct rohc_com
{
rohc_error(context->compressor, ROHC_TRACE_COMP, context->profile->id,
"failed to create W-LSB context for TCP sequence number");
- goto free_context;
+ goto free_wlsb_ipid;
}
tcp_context->seq_scaled_wlsb = c_create_wlsb(32, 4, 7);
if(tcp_context->seq_scaled_wlsb == NULL)
@@ -1095,6 +1108,8 @@ free_wlsb_seq_scaled:
c_destroy_wlsb(tcp_context->seq_scaled_wlsb);
free_wlsb_seq:
c_destroy_wlsb(tcp_context->seq_wlsb);
+free_wlsb_ipid:
+ c_destroy_wlsb(tcp_context->ipid_wlsb);
free_context:
c_generic_destroy(context);
error:
@@ -1124,6 +1139,7 @@ static void c_tcp_destroy(struct rohc_co
c_destroy_wlsb(tcp_context->ack_wlsb);
c_destroy_wlsb(tcp_context->seq_scaled_wlsb);
c_destroy_wlsb(tcp_context->seq_wlsb);
+ c_destroy_wlsb(tcp_context->ipid_wlsb);
c_generic_destroy(context);
}
@@ -4649,9 +4665,10 @@ static int co_baseheader(struct rohc_com
{
// =:= irregular(1) [ 1 ];
ret = c_optional_ip_id_lsb(context, ip_context.v4->ip_id_behavior,
- ip_context.v4->last_ip_id,
+ tcp_context->tmp.nr_ipid_bits_3,
tcp_context->tmp.ip_id,
- g_context->sn, mptr.uint8, &indicator);
+ tcp_context->tmp.ip_id_offset,
+ mptr.uint8, &indicator);
if(ret < 0)
{
rohc_comp_warn(context, "failed to encode optional_ip_id_lsb(ip_id)");
@@ -5286,7 +5303,6 @@ static size_t c_tcp_build_seq_1(struct r
{
struct c_generic_context *g_context;
uint32_t seq_num;
- uint16_t ip_id;
assert(context != NULL);
assert(context->specific != NULL);
@@ -5300,9 +5316,7 @@ static size_t c_tcp_build_seq_1(struct r
rohc_comp_debug(context, "code seq_1 packet");
seq1->discriminator = 0x0a; /* '1010' */
- ip_id = rohc_ntoh16(ip.ipv4->ip_id);
- seq1->ip_id = c_ip_id_lsb(context, ip_context.v4->ip_id_behavior, 4, 3,
- ip_context.v4->last_ip_id, ip_id, g_context->sn);
+ seq1->ip_id = tcp_context->tmp.ip_id_offset & 0x0f;
seq_num = rohc_ntoh32(tcp->seq_num) & 0xffff;
seq1->seq_num = rohc_hton16(seq_num);
seq1->msn = g_context->sn & 0xf;
@@ -5337,8 +5351,6 @@ static size_t c_tcp_build_seq_2(struct r
seq_2_t *const seq2)
{
struct c_generic_context *g_context;
- uint16_t ip_id;
- uint8_t ip_id_lsb;
assert(context != NULL);
assert(context->specific != NULL);
@@ -5352,11 +5364,8 @@ static size_t c_tcp_build_seq_2(struct r
rohc_comp_debug(context, "code seq_2 packet");
seq2->discriminator = 0x1a; /* '11010' */
- ip_id = rohc_ntoh16(ip.ipv4->ip_id);
- ip_id_lsb = c_ip_id_lsb(context, ip_context.v4->ip_id_behavior, 7, 3,
- ip_context.v4->last_ip_id, ip_id, g_context->sn);
- seq2->ip_id1 = (ip_id_lsb >> 4) & 0x7;
- seq2->ip_id2 = ip_id_lsb & 0x0f;
+ seq2->ip_id1 = (tcp_context->tmp.ip_id_offset >> 4) & 0x7;
+ seq2->ip_id2 = tcp_context->tmp.ip_id_offset & 0x0f;
seq2->seq_num_scaled = tcp_context->seq_num_scaled & 0xf;
seq2->msn = g_context->sn & 0xf;
seq2->psh_flag = tcp->psh_flag;
@@ -5390,7 +5399,6 @@ static size_t c_tcp_build_seq_3(struct r
seq_3_t *const seq3)
{
struct c_generic_context *g_context;
- uint16_t ip_id;
assert(context != NULL);
assert(context->specific != NULL);
@@ -5404,9 +5412,7 @@ static size_t c_tcp_build_seq_3(struct r
rohc_comp_debug(context, "code seq_3 packet");
seq3->discriminator = 0x09; /* '1001' */
- ip_id = rohc_ntoh16(ip.ipv4->ip_id);
- seq3->ip_id = c_ip_id_lsb(context, ip_context.v4->ip_id_behavior, 4, 3,
- ip_context.v4->last_ip_id, ip_id, g_context->sn);
+ seq3->ip_id = tcp_context->tmp.ip_id_offset & 0xf;
seq3->ack_num = rohc_hton16(rohc_ntoh32(tcp->ack_num) & 0xffff);
seq3->msn = g_context->sn & 0xf;
seq3->psh_flag = tcp->psh_flag;
@@ -5441,7 +5447,6 @@ static size_t c_tcp_build_seq_4(struct r
seq_4_t *const seq4)
{
struct c_generic_context *g_context;
- uint16_t ip_id;
assert(context != NULL);
assert(context->specific != NULL);
@@ -5457,9 +5462,7 @@ static size_t c_tcp_build_seq_4(struct r
seq4->discriminator = 0x00; /* '0' */
seq4->ack_num_scaled = tcp_context->ack_num_scaled & 0xf;
- ip_id = rohc_ntoh16(ip.ipv4->ip_id);
- seq4->ip_id = c_ip_id_lsb(context, ip_context.v4->ip_id_behavior, 3, 1,
- ip_context.v4->last_ip_id, ip_id, g_context->sn);
+ seq4->ip_id = tcp_context->tmp.ip_id_offset & 0x7;
seq4->msn = g_context->sn & 0xf;
seq4->psh_flag = tcp->psh_flag;
seq4->header_crc = 0; /* for CRC computation */
@@ -5494,7 +5497,6 @@ static size_t c_tcp_build_seq_5(struct r
{
struct c_generic_context *g_context;
uint32_t seq_num;
- uint16_t ip_id;
assert(context != NULL);
assert(context->specific != NULL);
@@ -5508,9 +5510,7 @@ static size_t c_tcp_build_seq_5(struct r
rohc_comp_debug(context, "code seq_5 packet");
seq5->discriminator = 0x08; /* '1000' */
- ip_id = rohc_ntoh16(ip.ipv4->ip_id);
- seq5->ip_id = c_ip_id_lsb(context, ip_context.v4->ip_id_behavior, 4, 3,
- ip_context.v4->last_ip_id, ip_id, g_context->sn);
+ seq5->ip_id = tcp_context->tmp.ip_id_offset & 0xf;
seq5->ack_num = rohc_hton16(rohc_ntoh32(tcp->ack_num) & 0xffff);
seq_num = rohc_ntoh32(tcp->seq_num) & 0xffff;
seq5->seq_num = rohc_hton16(seq_num);
@@ -5546,7 +5546,6 @@ static size_t c_tcp_build_seq_6(struct r
{
struct c_generic_context *g_context;
uint8_t seq_num_scaled;
- uint16_t ip_id;
assert(context != NULL);
assert(context->specific != NULL);
@@ -5567,9 +5566,7 @@ static size_t c_tcp_build_seq_6(struct r
seq6->seq_num_scaled2 = seq_num_scaled & 0x01;
/* IP-ID */
- ip_id = rohc_ntoh16(ip.ipv4->ip_id);
- seq6->ip_id = c_ip_id_lsb(context, ip_context.v4->ip_id_behavior, 7, 3,
- ip_context.v4->last_ip_id, ip_id, g_context->sn);
+ seq6->ip_id = tcp_context->tmp.ip_id_offset & 0x7f;
seq6->ack_num = rohc_hton16(rohc_ntoh32(tcp->ack_num) & 0xffff);
seq6->msn = g_context->sn & 0xf;
seq6->psh_flag = tcp->psh_flag;
@@ -5604,7 +5601,6 @@ static size_t c_tcp_build_seq_7(struct r
{
struct c_generic_context *g_context;
uint16_t window;
- uint16_t ip_id;
assert(context != NULL);
assert(context->specific != NULL);
@@ -5627,9 +5623,7 @@ static size_t c_tcp_build_seq_7(struct r
seq7->window3 = window & 0x07;
/* IP-ID */
- ip_id = rohc_ntoh16(ip.ipv4->ip_id);
- seq7->ip_id = c_ip_id_lsb(context, ip_context.v4->ip_id_behavior, 5, 3,
- ip_context.v4->last_ip_id, ip_id, g_context->sn);
+ seq7->ip_id = tcp_context->tmp.ip_id_offset & 0x1f;
seq7->ack_num = rohc_hton16(rohc_ntoh32(tcp->ack_num) & 0xffff);
seq7->msn = g_context->sn & 0xf;
seq7->psh_flag = tcp->psh_flag;
@@ -5668,7 +5662,6 @@ static bool c_tcp_build_seq_8(struct roh
size_t comp_opts_len;
uint16_t ack_num;
uint16_t seq_num;
- uint16_t ip_id;
bool is_ok;
assert(context != NULL);
@@ -5686,10 +5679,7 @@ static bool c_tcp_build_seq_8(struct roh
seq8->discriminator = 0x0b; /* '1011' */
/* IP-ID */
- ip_id = rohc_ntoh16(ip.ipv4->ip_id);
- seq8->ip_id = c_ip_id_lsb(context, ip_context.v4->ip_id_behavior, 4, 3,
- ip_context.v4->last_ip_id, ip_id, g_context->sn);
-
+ seq8->ip_id = tcp_context->tmp.ip_id_offset & 0xf;
seq8->list_present = 0; /* options are set later */
seq8->header_crc = 0; /* for CRC computation */
seq8->msn = g_context->sn & 0xf;
@@ -5986,36 +5976,6 @@ static bool tcp_encode_uncomp_fields(str
(inner_ip_ctxt.v4->last_ip_id_behavior != inner_ip_ctxt.v4->ip_id_behavior);
tcp_field_descr_change(context, "IP-ID behavior",
tcp_context->tmp.ip_id_behavior_changed);
- if(inner_ip_ctxt.vx->ip_id_behavior == IP_ID_BEHAVIOR_SEQ)
- {
- tcp_context->tmp.ip_id_hi9_changed =
- ((inner_ip_ctxt.v4->last_ip_id & 0xFF80) != (tcp_context->tmp.ip_id & 0xFF80));
- tcp_context->tmp.ip_id_hi11_changed =
- ((inner_ip_ctxt.v4->last_ip_id & 0xFFE0) != (tcp_context->tmp.ip_id & 0xFFE0));
- tcp_context->tmp.ip_id_hi12_changed =
- ((inner_ip_ctxt.v4->last_ip_id & 0xFFF0) != (tcp_context->tmp.ip_id & 0xFFF0));
- tcp_context->tmp.ip_id_hi13_changed =
- ((inner_ip_ctxt.v4->last_ip_id & 0xFFF8) != (tcp_context->tmp.ip_id & 0xFFF8));
- }
- else if(inner_ip_ctxt.vx->ip_id_behavior == IP_ID_BEHAVIOR_SEQ_SWAP)
- {
- tcp_context->tmp.ip_id_hi9_changed =
- ((inner_ip_ctxt.v4->last_ip_id & 0x80FF) != (tcp_context->tmp.ip_id & 0x80FF));
- tcp_context->tmp.ip_id_hi11_changed =
- ((inner_ip_ctxt.v4->last_ip_id & 0xE0FF) != (tcp_context->tmp.ip_id & 0xE0FF));
- tcp_context->tmp.ip_id_hi12_changed =
- ((inner_ip_ctxt.v4->last_ip_id & 0xF0FF) != (tcp_context->tmp.ip_id & 0xF0FF));
- tcp_context->tmp.ip_id_hi13_changed =
- ((inner_ip_ctxt.v4->last_ip_id & 0xF8FF) != (tcp_context->tmp.ip_id & 0xF8FF));
- }
- else
- {
- tcp_context->tmp.ip_id_hi9_changed = false; /* TODO: true/false ? */
- tcp_context->tmp.ip_id_hi11_changed = false; /* TODO: true/false ? */
- tcp_context->tmp.ip_id_hi12_changed = false; /* TODO: true/false ? */
- tcp_context->tmp.ip_id_hi13_changed = false; /* TODO: true/false ? */
- }
-
tcp_context->tmp.ip_df_changed =
(inner_ip_hdr.ipv4->df != inner_ip_ctxt.v4->df);
tcp_field_descr_change(context, "DF", tcp_context->tmp.ip_df_changed);
@@ -6024,16 +5984,78 @@ static bool tcp_encode_uncomp_fields(str
(inner_ip_hdr.ipv4->dscp != inner_ip_ctxt.v4->dscp);
tcp_field_descr_change(context, "DSCP", tcp_context->tmp.dscp_changed);
+ /* how many bits are required to encode the new IP-ID? */
+ if(context->state == ROHC_COMP_STATE_IR)
+ {
+ /* send all bits in IR state */
+ tcp_context->tmp.nr_ipid_bits_1 = 16;
+ tcp_context->tmp.nr_ipid_bits_3 = 16;
+ rohc_comp_debug(context, "IR state: force using 16 bits to encode "
+ "new IP-ID");
+ }
+ else if(inner_ip_ctxt.v4->ip_id_behavior != IP_ID_BEHAVIOR_SEQ &&
+ inner_ip_ctxt.v4->ip_id_behavior != IP_ID_BEHAVIOR_SEQ_SWAP)
+ {
+ /* send all bits if behavior is not sequential */
+ tcp_context->tmp.nr_ipid_bits_1 = 16;
+ tcp_context->tmp.nr_ipid_bits_3 = 16;
+ rohc_comp_debug(context, "IP-ID behavior changed: force using 16 "
+ "bits to encode new IP-ID");
+ }
+ else
+ {
+ /* send only required bits in FO or SO states and if behavior is
+ * sequential */
+
+ if(inner_ip_ctxt.v4->ip_id_behavior == IP_ID_BEHAVIOR_SEQ)
+ {
+ tcp_context->tmp.ip_id_offset =
+ tcp_context->tmp.ip_id - g_context->sn;
+ }
+ else
+ {
+ const uint16_t ip_id_nbo = swab16(tcp_context->tmp.ip_id);
+ tcp_context->tmp.ip_id_offset = ip_id_nbo - g_context->sn;
+ }
+
+ if(!wlsb_get_kp_32bits(tcp_context->ipid_wlsb,
+ tcp_context->tmp.ip_id_offset, 1,
+ &tcp_context->tmp.nr_ipid_bits_1))
+ {
+ rohc_warning(context->compressor, ROHC_TRACE_COMP,
+ context->profile->id, "failed to find the minimal "
+ "number of bits required for IP-ID offset 0x%04x "
+ "and p = 1", tcp_context->tmp.ip_id_offset);
+ goto error;
+ }
+ rohc_comp_debug(context, "%zd bits are required to encode new "
+ "IP-ID offset 0x%04x with p = 1",
+ tcp_context->tmp.nr_ipid_bits_1,
+ tcp_context->tmp.ip_id_offset);
+ if(!wlsb_get_kp_32bits(tcp_context->ipid_wlsb,
+ tcp_context->tmp.ip_id_offset, 3,
+ &tcp_context->tmp.nr_ipid_bits_3))
+ {
+ rohc_warning(context->compressor, ROHC_TRACE_COMP,
+ context->profile->id, "failed to find the minimal "
+ "number of bits required for IP-ID offset 0x%04x and "
+ "p = 3", tcp_context->tmp.ip_id_offset);
+ goto error;
+ }
+ rohc_comp_debug(context, "%zd bits are required to encode new IP-ID "
+ "offset 0x%04x with p = 3",
+ tcp_context->tmp.nr_ipid_bits_3,
+ tcp_context->tmp.ip_id_offset);
+ }
+ c_add_wlsb(tcp_context->ipid_wlsb, g_context->sn,
+ tcp_context->tmp.ip_id_offset);
+
tcp = (tcphdr_t *) (inner_ip_hdr.ipv4 + 1);
}
else
{
tcp_context->tmp.ip_id = 0;
tcp_context->tmp.ip_id_behavior_changed = false;
- tcp_context->tmp.ip_id_hi9_changed = false;
- tcp_context->tmp.ip_id_hi11_changed = false;
- tcp_context->tmp.ip_id_hi12_changed = false;
- tcp_context->tmp.ip_id_hi13_changed = false;
tcp_context->tmp.ip_df_changed = false;
tcp_context->tmp.dscp_changed =
@@ -6044,11 +6066,6 @@ static bool tcp_encode_uncomp_fields(str
tcp = (tcphdr_t *) (inner_ip_hdr.ipv6 + 1);
}
- rohc_comp_debug(context, "IP-ID: high 9 = %u, high 11 = %u, high 12 = %u, "
- "high 13 = %u", tcp_context->tmp.ip_id_hi9_changed,
- tcp_context->tmp.ip_id_hi11_changed,
- tcp_context->tmp.ip_id_hi12_changed,
- tcp_context->tmp.ip_id_hi13_changed);
seq_num_hbo = rohc_ntoh32(tcp->seq_num);
ack_num_hbo = rohc_ntoh32(tcp->ack_num);
@@ -6573,7 +6590,7 @@ static rohc_packet_t tcp_decide_SO_packe
* - at most 4 LSBs of IP-ID must be transmitted
* otherwise use co_common packet */
if(!tcp_context->tmp.tcp_window_changed &&
- !tcp_context->tmp.ip_id_hi12_changed && /* TODO: WLSB */
+ tcp_context->tmp.nr_ipid_bits_3 <= 4 &&
true /* TODO: list changed */ &&
true /* TODO: no more than 4 bits of SN */ &&
true /* TODO: no more than 3 bits of TTL */ &&
@@ -6594,7 +6611,7 @@ static rohc_packet_t tcp_decide_SO_packe
{
/* seq_7 or co_common */
if(/* TODO: no more than 15 bits of TCP window */
- !tcp_context->tmp.ip_id_hi11_changed && /* TODO: WLSB */
+ tcp_context->tmp.nr_ipid_bits_3 <= 5 &&
tcp_context->tmp.nr_ack_bits_32767 <= 16 &&
true /* TODO: no more than 4 bits of SN */ &&
tcp_context->tmp.tcp_rsf_flag_changed)
@@ -6613,7 +6630,7 @@ static rohc_packet_t tcp_decide_SO_packe
(tcp->ack_flag != 0 && !tcp_context->tmp.tcp_ack_num_changed))
{
/* seq_1, seq_2 or co_common */
- if(!tcp_context->tmp.ip_id_hi11_changed && /* TODO: WLSB */
+ if(tcp_context->tmp.nr_ipid_bits_3 <= 4 &&
tcp_context->tmp.nr_seq_bits_32767 <= 16 &&
true /* TODO: no more than 4 bits of SN */)
{
@@ -6621,7 +6638,7 @@ static rohc_packet_t tcp_decide_SO_packe
TRACE_GOTO_CHOICE;
packet_type = ROHC_PACKET_TCP_SEQ_1;
}
- else if(!tcp_context->tmp.ip_id_hi9_changed && /* TODO: WLSB */
+ else if(tcp_context->tmp.nr_ipid_bits_3 <= 7 &&
tcp_context->seq_num_scaling_nr >= ROHC_INIT_TS_STRIDE_MIN &&
tcp_context->tmp.nr_seq_scaled_bits <= 4 &&
true /* TODO: no more than 4 bits of SN */)
@@ -6642,14 +6659,14 @@ static rohc_packet_t tcp_decide_SO_packe
tcp_context->tmp.nr_seq_bits_8191 == 0)
{
/* seq_3, seq_4, or co_common */
- if(!tcp_context->tmp.ip_id_hi12_changed && /* TODO: WLSB */
+ if(tcp_context->tmp.nr_ipid_bits_3 <= 4 &&
tcp_context->tmp.nr_ack_bits_16383 <= 16 &&
true /* TODO: no more than 4 bits of SN */)
{
TRACE_GOTO_CHOICE;
packet_type = ROHC_PACKET_TCP_SEQ_3;
}
- else if(!tcp_context->tmp.ip_id_hi13_changed && /* TODO: WLSB */
+ else if(tcp_context->tmp.nr_ipid_bits_1 <= 3 &&
tcp_context->ack_stride != 0 &&
tcp_context->tmp.nr_ack_scaled_bits <= 4 &&
true /* TODO: no more than 4 bits of SN */)
@@ -6667,7 +6684,7 @@ static rohc_packet_t tcp_decide_SO_packe
{
/* sequence and acknowledgment numbers changed:
* seq_5, seq_6, seq_8 or co_common */
- if(!tcp_context->tmp.ip_id_hi12_changed && /* TODO: WLSB */
+ if(tcp_context->tmp.nr_ipid_bits_3 <= 4 &&
tcp_context->tmp.nr_ack_bits_16383 <= 16 &&
tcp_context->tmp.nr_seq_bits_32767 <= 16 &&
true /* TODO: no more than 4 bits of SN */)
@@ -6675,7 +6692,7 @@ static rohc_packet_t tcp_decide_SO_packe
TRACE_GOTO_CHOICE;
packet_type = ROHC_PACKET_TCP_SEQ_5;
}
- else if(!tcp_context->tmp.ip_id_hi9_changed && /* TODO: WLSB */
+ else if(tcp_context->tmp.nr_ipid_bits_3 <= 7 &&
tcp_context->seq_num_scaling_nr >= ROHC_INIT_TS_STRIDE_MIN &&
tcp_context->tmp.nr_seq_scaled_bits <= 4 &&
tcp_context->tmp.nr_ack_bits_16383 <= 16 &&
@@ -6685,7 +6702,7 @@ static rohc_packet_t tcp_decide_SO_packe
assert(tcp_context->tmp.payload_len > 0);
packet_type = ROHC_PACKET_TCP_SEQ_6;
}
- else if(!tcp_context->tmp.ip_id_hi12_changed && /* TODO: WLSB */
+ else if(tcp_context->tmp.nr_ipid_bits_3 <= 4 &&
true /* TODO: list changed */ &&
true /* TODO: no more than 4 bits of SN */ &&
true /* TODO: no more than 3 bits of TTL */ &&
=== modified file 'src/comp/schemes/rfc4996.c'
--- src/comp/schemes/rfc4996.c 2014-06-21 10:59:41 +0000
+++ src/comp/schemes/rfc4996.c 2014-07-20 09:13:07 +0000
@@ -453,72 +453,6 @@ unsigned int rsf_index_enc(const struct
/**
- * @brief Compress the lower bits of IP-ID
- *
- * See RFC4996 page 75
- *
- * @param context The compressor context
- * @param behavior The IP-ID behavior
- * @param k The num_lsbs_param parameter for c_lsb()
- * @param p The offset parameter for c_lsb()
- * @param context_ip_id The context value of IP-ID
- * @param ip_id The IP-ID value to compress
- * @param msn The Master Sequence Number
- * @return The lsb of offset between IP-ID and MSN
- */
-uint16_t c_ip_id_lsb(const struct rohc_comp_ctxt *const context,
- const int behavior,
- const unsigned int k,
- const unsigned int p,
- const uint16_t context_ip_id,
- const uint16_t ip_id,
- const uint16_t msn)
-{
- uint16_t ip_id_offset;
- uint16_t ip_id_nbo;
- uint16_t swapped_context_ip_id;
-
- assert(context != NULL);
- assert(behavior == IP_ID_BEHAVIOR_SEQ ||
- behavior == IP_ID_BEHAVIOR_SEQ_SWAP );
-
- rohc_comp_debug(context, "behavior = %d, context_ip_id = 0x%04x, "
- "ip_id = 0x%04x, msn = 0x%04x", behavior,
- context_ip_id, ip_id, msn);
-
- switch(behavior)
- {
- case IP_ID_BEHAVIOR_SEQ:
- ip_id_offset = ip_id - msn;
- rohc_comp_debug(context, "ip_id_offset = 0x%04x - 0x%04x = 0x%04x",
- ip_id, msn, ip_id_offset);
- ip_id_offset = c_lsb(context, k, p, context_ip_id - msn,
- ip_id_offset);
- rohc_comp_debug(context, "ip_id_offset = 0x%04x", ip_id_offset);
- break;
- case IP_ID_BEHAVIOR_SEQ_SWAP:
- ip_id_nbo = swab16(ip_id);
- rohc_comp_debug(context, "ip_id_nbo = 0x%04x", ip_id_nbo);
- ip_id_offset = ip_id_nbo - msn;
- rohc_comp_debug(context, "ip_id_offset = 0x%04x", ip_id_offset);
- swapped_context_ip_id = swab16(context_ip_id);
- ip_id_offset = c_lsb(context, k, p, swapped_context_ip_id - msn,
- ip_id_offset);
- rohc_comp_debug(context, "ip_id_offset = 0x%04x", ip_id_offset);
- break;
- default:
- /* should not happen */
-#if defined(NDEBUG) || defined(__KERNEL__) || defined(ENABLE_DEAD_CODE)
- ip_id_offset = 0;
-#endif
- assert(0);
- break;
- }
- return ip_id_offset;
-}
-
-
-/**
* @brief Compress or not the IP-ID
*
* See RFC4996 page 76
@@ -535,9 +469,9 @@ uint16_t c_ip_id_lsb(const struct rohc_c
*/
int c_optional_ip_id_lsb(const struct rohc_comp_ctxt *const context,
const int behavior,
- const uint16_t context_ip_id,
+ const size_t nr_ipid_bits_3,
const uint16_t ip_id,
- const uint16_t msn,
+ const uint16_t ip_id_offset,
uint8_t *const rohc_data,
int *const indicator)
{
@@ -545,17 +479,18 @@ int c_optional_ip_id_lsb(const struct ro
assert(context != NULL);
- rohc_comp_debug(context, "behavior = 0x%04x, context_ip_id = 0x%04x, "
- "ip_id = 0x%04x, msn = 0x%04x", behavior, context_ip_id,
- ip_id, msn);
+ rohc_comp_debug(context, "optional_ip_id_lsb: behavior = %d, "
+ "nr_ipid_bits_3 = %zu, ip_id = 0x%04x, "
+ "ip_id_offset = 0x%04x\n", behavior, nr_ipid_bits_3,
+ ip_id, ip_id_offset);
switch(behavior)
{
case IP_ID_BEHAVIOR_SEQ:
- if((context_ip_id & 0xff00) == (ip_id & 0xff00))
+ if(nr_ipid_bits_3 <= 8)
{
- rohc_data[0] = c_ip_id_lsb(context, behavior, 8, 3,
- context_ip_id, ip_id, msn);
+ /* short */
+ rohc_data[0] = ip_id_offset & 0xff;
*indicator = 0;
length++;
rohc_comp_debug(context, "write ip_id = 0x%02x", rohc_data[0]);
@@ -570,10 +505,10 @@ int c_optional_ip_id_lsb(const struct ro
}
break;
case IP_ID_BEHAVIOR_SEQ_SWAP:
- if((context_ip_id & 0x00ff) == (ip_id & 0x00ff))
+ if(nr_ipid_bits_3 <= 8)
{
- rohc_data[0] = c_ip_id_lsb(context, behavior, 8, 3,
- context_ip_id, ip_id, msn);
+ /* short */
+ rohc_data[0] = ip_id_offset & 0xff;
*indicator = 0;
length++;
rohc_comp_debug(context, "write ip_id = 0x%02x", rohc_data[0]);
@@ -597,7 +532,7 @@ int c_optional_ip_id_lsb(const struct ro
assert(0); /* should never happen */
*indicator = 0;
length = 0;
- break;
+ return -1;
}
return length;
=== modified file 'src/comp/schemes/rfc4996.h'
--- src/comp/schemes/rfc4996.h 2014-06-27 15:21:48 +0000
+++ src/comp/schemes/rfc4996.h 2014-07-20 09:03:11 +0000
@@ -158,22 +158,13 @@ void c_field_scaling(uint32_t *const sca
// RFC4996 page 71
unsigned int rsf_index_enc(const struct rohc_comp_ctxt *const context,
unsigned int rsf_flags);
-// RFC4996 page 75
-uint16_t c_ip_id_lsb(const struct rohc_comp_ctxt *const context,
- const int behavior,
- const unsigned int k,
- const unsigned int p,
- const uint16_t context_ip_id,
- const uint16_t ip_id,
- const uint16_t msn)
- __attribute__((warn_unused_result, nonnull(1)));
/* optional_ip_id_lsb encoding method */
int c_optional_ip_id_lsb(const struct rohc_comp_ctxt *const context,
const int behavior,
- const uint16_t context_ip_id,
+ const size_t nr_ipid_bits_3,
const uint16_t ip_id,
- const uint16_t msn,
+ const uint16_t ip_id_offset,
uint8_t *const rohc_data,
int *const indicator)
__attribute__((warn_unused_result, nonnull(1, 6, 7)));
=== modified file 'src/decomp/d_tcp.c'
--- src/decomp/d_tcp.c 2014-06-27 15:21:48 +0000
+++ src/decomp/d_tcp.c 2014-07-20 10:26:35 +0000
@@ -274,6 +274,8 @@ struct d_tcp_context
tcphdr_t old_tcphdr;
+ struct rohc_lsb_decode *ipid_lsb_ctxt;
+
uint8_t ip_context[MAX_IP_CONTEXT_SIZE];
};
@@ -429,6 +431,16 @@ static void * d_tcp_create(const struct
memset(tcp_context, 0, sizeof(struct d_tcp_context));
g_context->specific = tcp_context;
+ /* create the LSB decoding context for the IP-ID offset */
+ tcp_context->ipid_lsb_ctxt = rohc_lsb_new(ROHC_LSB_SHIFT_VAR, 16);
+ if(tcp_context->ipid_lsb_ctxt == NULL)
+ {
+ rohc_error(context->decompressor, ROHC_TRACE_DECOMP, context->profile->id,
+ "failed to create the LSB decoding context for the IP-ID "
+ "offset");
+ goto free_tcp_context;
+ }
+
/* create the LSB decoding context for the sequence number */
tcp_context->seq_lsb_ctxt = rohc_lsb_new(ROHC_LSB_SHIFT_VAR, 32);
if(tcp_context->seq_lsb_ctxt == NULL)
@@ -436,7 +448,7 @@ static void * d_tcp_create(const struct
rohc_error(context->decompressor, ROHC_TRACE_DECOMP, context->profile->id,
"failed to create the LSB decoding context for the sequence "
"number");
- goto free_tcp_context;
+ goto free_lsb_ipid;
}
/* create the LSB decoding context for the scaled sequence number */
@@ -540,6 +552,8 @@ free_lsb_scaled_seq:
rohc_lsb_free(tcp_context->seq_scaled_lsb_ctxt);
free_lsb_seq:
rohc_lsb_free(tcp_context->seq_lsb_ctxt);
+free_lsb_ipid:
+ rohc_lsb_free(tcp_context->ipid_lsb_ctxt);
free_tcp_context:
zfree(tcp_context);
destroy_context:
@@ -587,6 +601,8 @@ static void d_tcp_destroy(void *const co
rohc_lsb_free(tcp_context->seq_scaled_lsb_ctxt);
/* destroy the LSB decoding context for the sequence number */
rohc_lsb_free(tcp_context->seq_lsb_ctxt);
+ /* destroy the LSB decoding context for the IP-ID offset */
+ rohc_lsb_free(tcp_context->ipid_lsb_ctxt);
#if 0 /* TODO: sn_lsb_ctxt is not initialized, either remove it or use it fully */
/* destroy the LSB decoding context for SN */
@@ -839,6 +855,7 @@ static int d_tcp_decode_ir(struct rohc_d
struct d_tcp_context *tcp_context = g_context->specific;
ip_context_ptr_t ip_context;
base_header_ip_t base_header;
+ base_header_ip_t inner_ip_hdr;
tcphdr_t *tcp;
unsigned int payload_size;
const uint8_t *remain_data;
@@ -902,6 +919,7 @@ static int d_tcp_decode_ir(struct rohc_d
protocol = ip_context.vx->next_header;
ip_context.uint8 += ip_context.vx->context_length;
+ inner_ip_hdr.uint8 = base_header.uint8;
if(base_header.ipvx->version == IPV4)
{
base_header.ipv4->length = 0; /* force init to 0 */
@@ -984,6 +1002,7 @@ static int d_tcp_decode_ir(struct rohc_d
protocol = ip_context.vx->next_header;
ip_context.uint8 += ip_context.vx->context_length;
+ inner_ip_hdr.uint8 = base_header.uint8;
if(base_header.ipvx->version == IPV4)
{
++base_header.ipv4;
@@ -1093,6 +1112,7 @@ static int d_tcp_decode_ir(struct rohc_d
rohc_decomp_debug(context, "IP checksum = 0x%04x on %zu bytes",
rohc_ntoh16(base_header.ipv4->checksum),
base_header.ipv4->header_length * sizeof(uint32_t));
+ inner_ip_hdr.uint8 = base_header.uint8;
++base_header.ipv4;
++ip_context.v4;
uncomp_len -= sizeof(base_header_ip_v4_t);
@@ -1104,6 +1124,7 @@ static int d_tcp_decode_ir(struct rohc_d
base_header.ipv6->payload_length = rohc_hton16(uncomp_len);
rohc_decomp_debug(context, "IPv6 payload length = %d",
rohc_ntoh16(base_header.ipv6->payload_length));
+ inner_ip_hdr.uint8 = base_header.uint8;
++base_header.ipv6;
++ip_context.v6;
while(rohc_is_ipv6_opt(protocol))
@@ -1127,6 +1148,13 @@ static int d_tcp_decode_ir(struct rohc_d
rohc_lsb_set_ref(tcp_context->seq_lsb_ctxt, rohc_ntoh32(tcp->seq_num), false);
rohc_decomp_debug(context, "sequence number 0x%08x is the new reference",
rohc_ntoh32(tcp->seq_num));
+ if(inner_ip_hdr.ipvx->version == IPV4)
+ {
+ rohc_lsb_set_ref(tcp_context->ipid_lsb_ctxt,
+ rohc_ntoh16(inner_ip_hdr.ipv4->ip_id) - tcp_context->msn, false);
+ rohc_decomp_debug(context, "IP-ID offset 0x%04x is the new reference",
+ rohc_ntoh16(inner_ip_hdr.ipv4->ip_id) - tcp_context->msn);
+ }
if(payload_size != 0)
{
rohc_lsb_set_ref(tcp_context->seq_scaled_lsb_ctxt,
@@ -1171,6 +1199,7 @@ static int d_tcp_decode_irdyn(struct roh
struct d_tcp_context *tcp_context = g_context->specific;
ip_context_ptr_t ip_context;
base_header_ip_t base_header;
+ base_header_ip_t inner_ip_hdr;
tcphdr_t *tcp;
unsigned int payload_size;
const uint8_t *remain_data;
@@ -1232,6 +1261,7 @@ static int d_tcp_decode_irdyn(struct roh
protocol = ip_context.vx->next_header;
ip_context.uint8 += ip_context.vx->context_length;
+ inner_ip_hdr.uint8 = base_header.uint8;
if(base_header.ipvx->version == IPV4)
{
base_header.ipv4->length = 0; /* force init to 0 */
@@ -1328,6 +1358,7 @@ static int d_tcp_decode_irdyn(struct roh
rohc_decomp_debug(context, "IP checksum = 0x%04x for %d",
rohc_ntoh16(base_header.ipv4->checksum),
base_header.ipv4->header_length);
+ inner_ip_hdr.uint8 = base_header.uint8;
++base_header.ipv4;
++ip_context.v4;
uncomp_len -= sizeof(base_header_ip_v4_t);
@@ -1339,6 +1370,7 @@ static int d_tcp_decode_irdyn(struct roh
base_header.ipv6->payload_length = rohc_hton16(uncomp_len);
rohc_decomp_debug(context, "payload_length = %d",
rohc_ntoh16(base_header.ipv6->payload_length));
+ inner_ip_hdr.uint8 = base_header.uint8;
++base_header.ipv6;
++ip_context.v6;
while(rohc_is_ipv6_opt(protocol))
@@ -1366,6 +1398,13 @@ static int d_tcp_decode_irdyn(struct roh
rohc_lsb_set_ref(tcp_context->seq_lsb_ctxt, rohc_ntoh32(tcp->seq_num), false);
rohc_decomp_debug(context, "sequence number 0x%08x is the new reference",
rohc_ntoh32(tcp->seq_num));
+ if(inner_ip_hdr.ipvx->version == IPV4)
+ {
+ rohc_lsb_set_ref(tcp_context->ipid_lsb_ctxt,
+ rohc_ntoh16(inner_ip_hdr.ipv4->ip_id) - tcp_context->msn, false);
+ rohc_decomp_debug(context, "IP-ID offset 0x%04x is the new reference",
+ rohc_ntoh16(inner_ip_hdr.ipv4->ip_id) - tcp_context->msn);
+ }
if(payload_size != 0)
{
rohc_lsb_set_ref(tcp_context->seq_scaled_lsb_ctxt,
@@ -4429,6 +4468,7 @@ static int d_tcp_decode_CO(struct rohc_d
struct d_tcp_context *tcp_context;
ip_context_ptr_t ip_inner_context;
ip_context_ptr_t ip_context;
+ base_header_ip_t inner_ip_hdr;
uint16_t tcp_options_size = 0;
uint32_t seq_num_scaled_bits = 0;
size_t seq_num_scaled_nr = 0;
@@ -4440,6 +4480,7 @@ static int d_tcp_decode_CO(struct rohc_d
int size;
int ttl_irregular_chain_flag = 0;
int ip_inner_ecn;
+ uint16_t ip_id_offset;
uint16_t ip_id;
int ret;
@@ -5025,6 +5066,7 @@ static int d_tcp_decode_CO(struct rohc_d
#endif
base_header.ipv4->ttl_hopl = ip_context.v4->ttl_hopl;
protocol = ip_context.v4->protocol;
+ inner_ip_hdr.uint8 = base_header.uint8;
++base_header.ipv4;
++ip_context.v4;
}
@@ -5035,6 +5077,7 @@ static int d_tcp_decode_CO(struct rohc_d
base_header.ipv6->dscp2 = ip_context.v6->dscp & 0x03;
base_header.ipv6->ttl_hopl = ip_context.v6->ttl_hopl;
protocol = ip_context.v6->next_header;
+ inner_ip_hdr.uint8 = base_header.uint8;
++base_header.ipv6;
++ip_context.v6;
}
@@ -5135,17 +5178,20 @@ static int d_tcp_decode_CO(struct rohc_d
/* IP-ID behavior */
ip_inner_context.v4->ip_id_behavior = co_common->ip_id_behavior;
ret = d_optional_ip_id_lsb(context, rohc_opts_data,
+ tcp_context->ipid_lsb_ctxt,
co_common->ip_id_behavior,
co_common->ip_id_indicator,
- ip_inner_context.v4->last_ip_id,
- &ip_id, msn);
+ msn, &ip_id_offset, &ip_id);
if(ret < 0)
{
rohc_decomp_warn(context, "optional_ip_id_lsb(ip_id) failed");
goto error;
}
- rohc_decomp_debug(context, "IP-ID = 0x%04x (%d bytes in packet)",
- ip_id, ret);
+ if(co_common->ip_id_behavior != IP_ID_BEHAVIOR_RAND)
+ {
+ rohc_decomp_debug(context, "IP-ID = 0x%04x (%d bytes in packet)",
+ ip_id, ret);
+ }
rohc_opts_data += ret;
/* URG pointer */
@@ -5241,6 +5287,7 @@ static int d_tcp_decode_CO(struct rohc_d
uint32_t ack_num_p;
uint32_t ack_num_scaled;
uint8_t ttl_hopl;
+ bool decode_ok;
tcp->seq_num = tcp_context->old_tcphdr.seq_num;
tcp->ack_num = tcp_context->old_tcphdr.ack_num;
@@ -5452,9 +5499,15 @@ static int d_tcp_decode_CO(struct rohc_d
rohc_decomp_debug(context, "decode seq_1 packet");
- ip_id = d_ip_id_lsb(context, ip_inner_context.v4->ip_id_behavior,
- 4, 3, ip_inner_context.v4->last_ip_id,
- seq_1->ip_id, msn);
+ decode_ok = d_ip_id_lsb(context, tcp_context->ipid_lsb_ctxt,
+ ip_inner_context.v4->ip_id_behavior, msn,
+ seq_1->ip_id, 4, 3, &ip_id_offset, &ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
/* decode sequence number from packet bits and context */
encoded_seq_num = rohc_ntoh16(seq_1->seq_num);
@@ -5476,9 +5529,15 @@ static int d_tcp_decode_CO(struct rohc_d
rohc_decomp_debug(context, "decode seq_2 packet");
ip_id_lsb = (seq_2->ip_id1 << 4) | seq_2->ip_id2;
- ip_id = d_ip_id_lsb(context, ip_inner_context.v4->ip_id_behavior,
- 7, 3, ip_inner_context.v4->last_ip_id,
- ip_id_lsb, msn);
+ decode_ok = d_ip_id_lsb(context, tcp_context->ipid_lsb_ctxt,
+ ip_inner_context.v4->ip_id_behavior, msn,
+ ip_id_lsb, 7, 3, &ip_id_offset, &ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
seq_num_scaled_bits = seq_2->seq_num_scaled;
seq_num_scaled_nr = 4;
rohc_decomp_debug(context, "seq_2: %zu bits of scaled sequence "
@@ -5493,9 +5552,15 @@ static int d_tcp_decode_CO(struct rohc_d
rohc_decomp_debug(context, "decode seq_3 packet");
- ip_id = d_ip_id_lsb(context, ip_inner_context.v4->ip_id_behavior,
- 4, 3, ip_inner_context.v4->last_ip_id,
- seq_3->ip_id, msn);
+ decode_ok = d_ip_id_lsb(context, tcp_context->ipid_lsb_ctxt,
+ ip_inner_context.v4->ip_id_behavior, msn,
+ seq_3->ip_id, 4, 3, &ip_id_offset, &ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
/* retrieve ACK number bits */
ack_num_bits = rohc_ntoh16(seq_3->ack_num);
@@ -5529,9 +5594,17 @@ static int d_tcp_decode_CO(struct rohc_d
"0x%x", ack_num_scaled,
tcp_context->ack_num_residue,
rohc_ntoh32(tcp->ack_num));
- ip_id = d_ip_id_lsb(context, ip_inner_context.v4->ip_id_behavior,
- 3, 1, ip_inner_context.v4->last_ip_id,
- seq_4->ip_id, msn);
+
+ decode_ok = d_ip_id_lsb(context, tcp_context->ipid_lsb_ctxt,
+ ip_inner_context.v4->ip_id_behavior, msn,
+ seq_4->ip_id, 3, 1, &ip_id_offset, &ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
+
tcp->psh_flag = seq_4->psh_flag;
break;
}
@@ -5542,9 +5615,16 @@ static int d_tcp_decode_CO(struct rohc_d
uint32_t decoded_seq_num;
rohc_decomp_debug(context, "decode seq_5 packet");
- ip_id = d_ip_id_lsb(context, ip_inner_context.v4->ip_id_behavior,
- 4, 3, ip_inner_context.v4->last_ip_id,
- seq_5->ip_id, msn);
+
+ decode_ok = d_ip_id_lsb(context, tcp_context->ipid_lsb_ctxt,
+ ip_inner_context.v4->ip_id_behavior, msn,
+ seq_5->ip_id, 4, 3, &ip_id_offset, &ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
/* retrieve ACK number bits */
ack_num_bits = rohc_ntoh16(seq_5->ack_num);
@@ -5575,9 +5655,16 @@ static int d_tcp_decode_CO(struct rohc_d
rohc_decomp_debug(context, "seq_6: %zu bits of scaled sequence "
"number 0x%x", seq_num_scaled_nr,
seq_num_scaled_bits);
- ip_id = d_ip_id_lsb(context, ip_inner_context.v4->ip_id_behavior,
- 7, 3, ip_inner_context.v4->last_ip_id,
- seq_6->ip_id, msn);
+
+ decode_ok = d_ip_id_lsb(context, tcp_context->ipid_lsb_ctxt,
+ ip_inner_context.v4->ip_id_behavior, msn,
+ seq_6->ip_id, 7, 3, &ip_id_offset, &ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
/* retrieve ACK number bits */
ack_num_bits = rohc_ntoh16(seq_6->ack_num);
@@ -5597,9 +5684,16 @@ static int d_tcp_decode_CO(struct rohc_d
window = (seq_7->window1 << 11) | (seq_7->window2 << 3) |
seq_7->window3;
tcp->window = rohc_hton16( d_lsb(context, 15,16383,rohc_ntoh16(tcp_context->old_tcphdr.window),window) );
- ip_id = d_ip_id_lsb(context, ip_inner_context.v4->ip_id_behavior,
- 5, 3, ip_inner_context.v4->last_ip_id,
- seq_7->ip_id, msn);
+
+ decode_ok = d_ip_id_lsb(context, tcp_context->ipid_lsb_ctxt,
+ ip_inner_context.v4->ip_id_behavior, msn,
+ seq_7->ip_id, 5, 3, &ip_id_offset, &ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
/* retrieve ACK number bits */
ack_num_bits = rohc_ntoh16(seq_7->ack_num);
@@ -5616,9 +5710,17 @@ static int d_tcp_decode_CO(struct rohc_d
uint16_t enc_seq_num;
rohc_decomp_debug(context, "decode seq_8 packet");
- ip_id = d_ip_id_lsb(context, ip_inner_context.v4->ip_id_behavior,
- 4, 3, ip_inner_context.v4->last_ip_id,
- seq_8->ip_id, msn);
+
+ decode_ok = d_ip_id_lsb(context, tcp_context->ipid_lsb_ctxt,
+ ip_inner_context.v4->ip_id_behavior, msn,
+ seq_8->ip_id, 4, 3, &ip_id_offset, &ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
+
tcp->psh_flag = seq_8->psh_flag;
ttl_hopl = d_lsb(context, 3, 3, ip_inner_context.vx->ttl_hopl,
seq_8->ttl_hopl);
@@ -5761,6 +5863,8 @@ static int d_tcp_decode_CO(struct rohc_d
}
base_header_inner.ipv4->ip_id = rohc_hton16(ip_id);
ip_inner_context.v4->last_ip_id = ip_id;
+ rohc_decomp_debug(context, "new last IP-ID = 0x%04x",
+ ip_inner_context.v4->last_ip_id);
break;
}
case IP_ID_BEHAVIOR_SEQ_SWAP:
@@ -5780,6 +5884,8 @@ static int d_tcp_decode_CO(struct rohc_d
base_header_inner.ipv4->ip_id = rohc_hton16(swapped_ip_id);
ip_inner_context.v4->last_ip_id = swapped_ip_id;
+ rohc_decomp_debug(context, "new last IP-ID = 0x%04x",
+ ip_inner_context.v4->last_ip_id);
break;
}
case IP_ID_BEHAVIOR_RAND:
@@ -5964,6 +6070,12 @@ static int d_tcp_decode_CO(struct rohc_d
rohc_lsb_set_ref(tcp_context->seq_lsb_ctxt, rohc_ntoh32(tcp->seq_num), false);
rohc_decomp_debug(context, "sequence number 0x%08x is the new reference",
rohc_ntoh32(tcp->seq_num));
+ if(inner_ip_hdr.ipvx->version == IPV4)
+ {
+ rohc_lsb_set_ref(tcp_context->ipid_lsb_ctxt, ip_id - msn, false);
+ rohc_decomp_debug(context, "IP-ID offset 0x%04x is the new reference",
+ ip_id - msn);
+ }
if(payload_len != 0)
{
rohc_lsb_set_ref(tcp_context->seq_scaled_lsb_ctxt,
=== modified file 'src/decomp/schemes/rfc4996.c'
--- src/decomp/schemes/rfc4996.c 2014-06-21 10:59:41 +0000
+++ src/decomp/schemes/rfc4996.c 2014-07-20 10:05:43 +0000
@@ -42,21 +42,6 @@
#include <assert.h>
-/* TODO: to be removed once c_lsb and d_c_lsb are removed */
-/**
- * @brief Table of the mask for lsb()
- */
-static unsigned int lsb_masks[] =
-{
- 0x00000,
- 0x00001, 0x00003, 0x00007, 0x0000F,
- 0x0001F, 0x0003F, 0x0007F, 0x000FF,
- 0x001FF, 0x003FF, 0x007FF, 0x00FFF,
- 0x01FFF, 0x03FFF, 0x07FFF, 0x0FFFF,
- 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF
-};
-
-
/**
* @brief Table of the mask for lsb()
*/
@@ -350,106 +335,71 @@ unsigned int rsf_index_dec( unsigned int
/**
- * @brief Compress the lower bits of the given value.
- *
- * See RFC4997 page 27
- *
- * @param context The compressor context
- * @param num_lsbs_param The number of bits
- * @param offset_param The offset
- * @param context_value The value of the context
- * @param original_value The value to compress
- * @return The compressed value with num_lsbs_param bits
- *
- * @todo TODO: duplicated code from rfc4996_encoding.c
- */
-static uint32_t d_c_lsb(const struct rohc_decomp_ctxt *const context,
- int num_lsbs_param,
- unsigned int offset_param,
- unsigned int context_value,
- unsigned int original_value)
-{
- unsigned int lower_bound;
- unsigned int upper_bound;
- unsigned int value;
-
- assert(context != NULL);
-
- rohc_decomp_debug(context, "num_lsb = %d, offset_param = %d, "
- "context_value = 0x%x, original_value = 0x%x",
- num_lsbs_param, offset_param, context_value,
- original_value);
-
- assert( num_lsbs_param > 0 && num_lsbs_param <= 18 );
-
- lower_bound = context_value - offset_param;
- upper_bound = context_value + lsb_masks[num_lsbs_param] - offset_param;
-
- value = original_value & lsb_masks[num_lsbs_param];
-
- rohc_decomp_debug(context, "0x%x < value (0x%x) < 0x%x => return 0x%x",
- lower_bound, original_value, upper_bound, value);
-
- return value;
-}
-
-
-/**
* @brief Decompress the lower bits of IP-ID
*
* See RFC4996 page 75
*
* @param context The decompression context
+ * @param lsb The LSB decompression context
* @param behavior The IP-ID behavior
* @param k The num_lsbs_param parameter for d_lsb()
* @param p The offset parameter for d_lsb()
* @param context_ip_id The context IP-ID value
* @param value The value to decompress
* @param msn The Master Sequence Number
- * @return The IP-ID
*/
-uint16_t d_ip_id_lsb(const struct rohc_decomp_ctxt *const context,
- const int behavior,
- const unsigned int k,
- const unsigned int p,
- const uint16_t context_ip_id,
- const uint16_t value,
- const uint16_t msn)
+bool d_ip_id_lsb(const struct rohc_decomp_ctxt *const context,
+ const struct rohc_lsb_decode *const lsb,
+ const int behavior,
+ const uint32_t msn,
+ const uint16_t ip_id_bits,
+ const uint16_t ip_id_bits_nr,
+ const rohc_lsb_shift_t p,
+ uint16_t *const ip_id_offset,
+ uint16_t *const ip_id)
{
- uint16_t ip_id_offset;
- uint16_t ip_id;
+ uint32_t ip_id_offset32;
+ bool decode_ok;
- assert(context != NULL);
+ assert(behavior == IP_ID_BEHAVIOR_SEQ ||
+ behavior == IP_ID_BEHAVIOR_SEQ_SWAP);
- rohc_decomp_debug(context, "behavior = %d, k = %d, p = %d, "
- "context_ip_id = 0x%04x, value = 0x%04x, msn = 0x%04x",
- behavior, k, p, context_ip_id, value, msn);
+ rohc_decomp_debug(context, "ip_id_lsb: behavior = %d, MSN = 0x%02x, "
+ "%zu-bits 0x%x, p = %d", behavior, msn, ip_id_bits_nr,
+ ip_id_bits, p);
+
+ /* decode the IP-ID offset with LSB */
+ decode_ok = rohc_lsb_decode(lsb, ROHC_LSB_REF_0, 0, ip_id_bits,
+ ip_id_bits_nr, p, &ip_id_offset32);
+ if(!decode_ok)
+ {
+ rohc_warning(context->decompressor, ROHC_TRACE_DECOMP, context->profile->id,
+ "failed to decode %zu IP-ID offset bits 0x%x with "
+ "p = %u", ip_id_bits_nr, ip_id_bits, p);
+ goto error;
+ }
+ assert((ip_id_offset32 & 0xffff) == ip_id_offset32);
+ *ip_id_offset = (uint16_t) ip_id_offset32;
+ rohc_decomp_debug(context, "decoded IP-ID offset = 0x%04x (%zu bits "
+ "0x%x with p = %d)", *ip_id_offset, ip_id_bits_nr,
+ ip_id_bits, p);
- switch(behavior)
+ /* compute the IP-ID from the IP-ID offset */
+ if(behavior == IP_ID_BEHAVIOR_SEQ)
{
- case IP_ID_BEHAVIOR_SEQ:
- ip_id = context_ip_id + 1;
- ip_id_offset = ip_id - msn;
- ip_id_offset = d_c_lsb(context, k, p, context_ip_id - msn,
- ip_id_offset);
- rohc_decomp_debug(context, "new ip_id = 0x%04x, ip_id_offset = "
- "0x%04x, value = 0x%04x", ip_id, ip_id_offset,
- value);
- assert(ip_id_offset == value); /* TODO: should not assert */
- return ip_id;
- case IP_ID_BEHAVIOR_SEQ_SWAP:
- ip_id = swab16(context_ip_id);
- ip_id++;
- ip_id_offset = ip_id - msn;
- ip_id_offset = d_c_lsb(context, k, p, ip_id - 1 - msn, ip_id_offset);
- rohc_decomp_debug(context, "new ip_id = 0x%04x, ip_id_offset = "
- "0x%04x, value = 0x%04x", ip_id, ip_id_offset,
- value);
- assert(ip_id_offset == value); /* TODO: should not assert */
- return ip_id;
+ *ip_id = (*ip_id_offset) + msn;
+ }
+ else /* IP_ID_BEHAVIOR_SEQ_SWAP */
+ {
+ /* compute the IP-ID from the IP-ID offset */
+ *ip_id = swab16((*ip_id_offset) + msn);
}
+ rohc_decomp_debug(context, "decoded IP-ID = 0x%04x", *ip_id);
- return 0;
+ return true;
+
+error:
+ return false;
}
@@ -470,30 +420,38 @@ uint16_t d_ip_id_lsb(const struct rohc_d
*/
int d_optional_ip_id_lsb(const struct rohc_decomp_ctxt *const context,
const uint8_t *const rohc_data,
+ const struct rohc_lsb_decode *const lsb,
const int behavior,
const int indicator,
- const uint16_t context_ip_id,
- uint16_t *const ip_id,
- const uint16_t msn)
+ const uint16_t msn,
+ uint16_t *const ip_id_offset,
+ uint16_t *const ip_id)
{
size_t length = 0;
assert(context != NULL);
- rohc_decomp_debug(context, "behavior = %d, indicator = %d, "
- "context_ip_id = 0x%04x, msn = 0x%04x", behavior,
- indicator, context_ip_id, msn);
+ rohc_decomp_debug(context, "optional_ip_id_lsb: behavior = %d, "
+ "indicator = %d, MSN = 0x%04x", behavior, indicator,
+ msn);
switch(behavior)
{
case IP_ID_BEHAVIOR_SEQ:
if(indicator == 0)
{
- *ip_id = (context_ip_id & 0xff00) |
- d_ip_id_lsb(context, behavior, 8, 3, context_ip_id,
- rohc_data[0], msn);
- rohc_decomp_debug(context, "read ip_id = 0x%04x -> 0x%04x",
- rohc_data[0], *ip_id);
+ const uint16_t ip_id_lsb = rohc_data[0] & 0xff;
+ const bool decode_ok =
+ d_ip_id_lsb(context, lsb, behavior, msn, ip_id_lsb, 8, 3,
+ ip_id_offset, ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
+ rohc_decomp_debug(context, "decoded IP-ID from 8-bit LSB encoded "
+ "0x%02x = 0x%04x", rohc_data[0], *ip_id);
length++;
}
else
@@ -501,19 +459,25 @@ int d_optional_ip_id_lsb(const struct ro
memcpy(ip_id, rohc_data, sizeof(uint16_t));
length += sizeof(uint16_t);
*ip_id = rohc_ntoh16(*ip_id);
- rohc_decomp_debug(context, "read ip_id = 0x%04x", *ip_id);
+ *ip_id_offset = (*ip_id) - msn;
+ rohc_decomp_debug(context, "irregular IP-ID = 0x%04x", *ip_id);
}
break;
case IP_ID_BEHAVIOR_SEQ_SWAP:
- {
- const uint16_t swapped_context_ip_id = swab16(context_ip_id);
if(indicator == 0)
{
- *ip_id = (swapped_context_ip_id & 0xff00) |
- d_ip_id_lsb(context, behavior, 8, 3, context_ip_id,
- rohc_data[0], msn);
- rohc_decomp_debug(context, "read ip_id = 0x%04x -> 0x%04x",
- rohc_data[0], *ip_id);
+ const uint16_t ip_id_lsb = rohc_data[0] & 0xff;
+ const bool decode_ok =
+ d_ip_id_lsb(context, lsb, behavior, msn, ip_id_lsb, 8, 3,
+ ip_id_offset, ip_id);
+ if(!decode_ok)
+ {
+ rohc_decomp_warn(context, "failed to decode the W-LSB-encoded "
+ "IP-ID offset");
+ goto error;
+ }
+ rohc_decomp_debug(context, "decoded IP-ID from 8-bit LSB encoded "
+ "0x%02x = 0x%04x", rohc_data[0], *ip_id);
length++;
}
else
@@ -521,10 +485,10 @@ int d_optional_ip_id_lsb(const struct ro
memcpy(ip_id, rohc_data, sizeof(uint16_t));
length += sizeof(uint16_t);
*ip_id = rohc_ntoh16(*ip_id);
- rohc_decomp_debug(context, "read ip_id = 0x%04x", *ip_id);
+ *ip_id_offset = (*ip_id) - msn;
+ rohc_decomp_debug(context, "irregular IP-ID = 0x%04x", *ip_id);
}
break;
- }
case IP_ID_BEHAVIOR_RAND:
break;
case IP_ID_BEHAVIOR_ZERO:
@@ -535,6 +499,9 @@ int d_optional_ip_id_lsb(const struct ro
}
return length;
+
+error:
+ return -1;
}
=== modified file 'src/decomp/schemes/rfc4996.h'
--- src/decomp/schemes/rfc4996.h 2014-06-27 15:21:48 +0000
+++ src/decomp/schemes/rfc4996.h 2014-07-20 10:02:57 +0000
@@ -83,24 +83,27 @@ uint32_t d_field_scaling(const uint32_t
unsigned int rsf_index_dec( unsigned int rsf_index );
// RFC4996 page 75
-uint16_t d_ip_id_lsb(const struct rohc_decomp_ctxt *const context,
- const int behavior,
- const unsigned int k,
- const unsigned int p,
- const uint16_t context_ip_id,
- const uint16_t value,
- const uint16_t msn)
- __attribute__((warn_unused_result, nonnull(1)));
+bool d_ip_id_lsb(const struct rohc_decomp_ctxt *const context,
+ const struct rohc_lsb_decode *const lsb,
+ const int behavior,
+ const uint32_t msn,
+ const uint16_t ip_id_bits,
+ const uint16_t ip_id_bits_nr,
+ const rohc_lsb_shift_t p,
+ uint16_t *const ip_id_offset,
+ uint16_t *const ip_id)
+ __attribute__((warn_unused_result, nonnull(1, 2, 8, 9)));
// RFC4996 page 76
int d_optional_ip_id_lsb(const struct rohc_decomp_ctxt *const context,
const uint8_t *const rohc_data,
+ const struct rohc_lsb_decode *const lsb,
const int behavior,
const int indicator,
- const uint16_t context_ip_id,
- uint16_t *const ip_id,
- const uint16_t msn)
- __attribute__((warn_unused_result, nonnull(1, 2, 6)));
+ const uint16_t msn,
+ uint16_t *const ip_id_offset,
+ uint16_t *const ip_id)
+ __attribute__((warn_unused_result, nonnull(1, 2, 3, 7, 8)));
int dscp_decode(const uint8_t *const rohc_data,
const uint8_t context_value,
Attachment:
signature.asc
Description: PGP signature
References