result of rohc_compress() is not correct

Asked by Wei Wang on 2013-05-09

Hi Didier,

I'm trying to use rohc lib. The result is not right. I basically used the sample data provided by simple_rohc_program.c. Code snippet is as following, which shows what I did:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        int BUFFER_SIZE = 2048;
 unsigned char rohc_packet[BUFFER_SIZE]; /* the buffer that will contain
                                            the resulting ROHC packet */
 int rohc_packet_len; /* the length (in bytes) of the
                                            resulting ROHC packet */
        int ip_packet_len;
        unsigned char ip_packet[BUFFER_SIZE];
        char FAKE_PAYLOAD[] = "hello, ROHC world!";

 ip_packet[0] = 4 << 4; /* IP version 4 */
 ip_packet[0] |= 5; /* IHL: minimal IPv4 header length (in 32-bit words) */
 ip_packet[1] = 0; /* TOS */
 ip_packet_len = 5 * 4 + strlen(FAKE_PAYLOAD);
 ip_packet[2] = (htons(ip_packet_len) >> 8) & 0xff; /* Total Length */
 ip_packet[3] = htons(ip_packet_len) & 0xff;
 ip_packet[4] = 0; /* IP-ID */
 ip_packet[5] = 0;
 ip_packet[6] = 0; /* Fragment Offset and IP flags */
 ip_packet[7] = 0;
 ip_packet[8] = 1; /* TTL */
 ip_packet[9] = 134; /* Protocol: unassigned number */
 ip_packet[10] = 0xbe; /* fake Checksum */
 ip_packet[11] = 0xef;
 ip_packet[12] = 0x01; /* Source address */
 ip_packet[13] = 0x02;
 ip_packet[14] = 0x03;
 ip_packet[15] = 0x04;
 ip_packet[16] = 0x05; /* Destination address */
 ip_packet[17] = 0x06;
 ip_packet[18] = 0x07;
 ip_packet[19] = 0x08;

 /* copy the payload just after the IP header */
 memcpy(ip_packet + 5 * 4, FAKE_PAYLOAD, strlen(FAKE_PAYLOAD));

        compressor = rohc_alloc_compressor(ROHC_SMALL_CID_MAX, 0, 0, 0);

        rohc_activate_profile(compressor, ROHC_PROFILE_UNCOMPRESSED);
        rohc_activate_profile(compressor, ROHC_PROFILE_IP);

 int ret_size = rohc_compress(compressor,
                      ip_packet, ip_packet_len,
                      rohc_packet, BUFFER_SIZE);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I printed the result. And I saw nothing changed in the output rohc_packet except the size increased by 3 bytes.
rohc_packet[ 0 ] = 0xfc
rohc_packet[ 1 ] = 0x0
rohc_packet[ 2 ] = 0xb7
rohc_packet[ 3 ] = 0x45
rohc_packet[ 4 ] = 0x0
rohc_packet[ 5 ] = 0x26
rohc_packet[ 6 ] = 0x0
rohc_packet[ 7 ] = 0x0
rohc_packet[ 8 ] = 0x0
rohc_packet[ 9 ] = 0x0
rohc_packet[ 10 ] = 0x0
rohc_packet[ 11 ] = 0x1
rohc_packet[ 12 ] = 0x86
rohc_packet[ 13 ] = 0xbe
rohc_packet[ 14 ] = 0xef
rohc_packet[ 15 ] = 0x1
rohc_packet[ 16 ] = 0x2
rohc_packet[ 17 ] = 0x3
rohc_packet[ 18 ] = 0x4
rohc_packet[ 19 ] = 0x5
rohc_packet[ 20 ] = 0x6
rohc_packet[ 21 ] = 0x7
rohc_packet[ 22 ] = 0x8
rohc_packet[ 23 ] = 0x68
rohc_packet[ 24 ] = 0x65
rohc_packet[ 25 ] = 0x6c
rohc_packet[ 26 ] = 0x6c
rohc_packet[ 27 ] = 0x6f
rohc_packet[ 28 ] = 0x2c
rohc_packet[ 29 ] = 0x20
rohc_packet[ 30 ] = 0x52
rohc_packet[ 31 ] = 0x4f
rohc_packet[ 32 ] = 0x48
rohc_packet[ 33 ] = 0x43
rohc_packet[ 34 ] = 0x20
rohc_packet[ 35 ] = 0x77
rohc_packet[ 36 ] = 0x6f
rohc_packet[ 37 ] = 0x72
rohc_packet[ 38 ] = 0x6c
rohc_packet[ 39 ] = 0x64
rohc_packet[ 40 ] = 0x21
You can see from the 4th byte on, everything is exactly the same as those before rohc_compress() was called. Did I miss any step in order to use this function correctly?

Thanks in advance.

Regards,
Wei

Question information

Language:
English Edit question
Status:
Solved
For:
rohc Edit question
Assignee:
No assignee Edit question
Solved by:
Wei Wang
Solved:
2013-05-22
Last query:
2013-05-22
Last reply:
2013-05-14

Wei,

> I'm trying to use rohc lib. The result is not right. I basically used the sample
> data provided by simple_rohc_program.c. Code snippet is as following, which
> shows what I did:
> [...]

The resulting packet is a valid ROHC packet. It is a ROHC packet that uses the Uncompressed profile. That's why you recognize the original non-compressed packet starting from the 4th byte.

However, there is something wrong with the example application. It should compress the IP packet with the best profile that was enabled, ie. the IP-only profile. That's not the case because I made a mistake when building the fake IP packet. The Total Length field is in Host Byte Order instead of Network Byte Order. The ROHC library therefore detects that the packet is not a valid IP packet. In consequence it chooses the Uncompressed profile instead of the IP-only profile.

I opened a ticket [1] and fixed the problem in the 1.5.x and main branches. Thank you for reporting the problem!

Regards,
Didier

[1] https://bugs.launchpad.net/rohc/+bug/1178441

Wei Wang (eww012) said : #2

Hi Didier,

First, thanks for your I tried your change in sample file.
 ip_packet[2] = (ip_packet_len >> 8) & 0xff; /* Total Length */
 ip_packet[3] = ip_packet_len & 0xff;

However, the result is not right. Can you please take a look one more time? The original IP packet size is 38 (20 IP header bytes + 18 fake payload size) and the size after rohc_compress() is 39.

rohc_packet[ 0 ] = 0xfd
rohc_packet[ 1 ] = 0x4
rohc_packet[ 2 ] = 0x21
rohc_packet[ 3 ] = 0x40
rohc_packet[ 4 ] = 0x86
rohc_packet[ 5 ] = 0x1
rohc_packet[ 6 ] = 0x2
rohc_packet[ 7 ] = 0x3
rohc_packet[ 8 ] = 0x4
rohc_packet[ 9 ] = 0x5
rohc_packet[ 10 ] = 0x6
rohc_packet[ 11 ] = 0x7
rohc_packet[ 12 ] = 0x8
rohc_packet[ 13 ] = 0x0
rohc_packet[ 14 ] = 0x1
rohc_packet[ 15 ] = 0x0
rohc_packet[ 16 ] = 0x0
rohc_packet[ 17 ] = 0x20
rohc_packet[ 18 ] = 0x0
rohc_packet[ 19 ] = 0x0
rohc_packet[ 20 ] = 0x1
rohc_packet[ 21 ] = 0x68
rohc_packet[ 22 ] = 0x65
rohc_packet[ 23 ] = 0x6c
rohc_packet[ 24 ] = 0x6c
rohc_packet[ 25 ] = 0x6f
rohc_packet[ 26 ] = 0x2c
rohc_packet[ 27 ] = 0x20
rohc_packet[ 28 ] = 0x52
rohc_packet[ 29 ] = 0x4f
rohc_packet[ 30 ] = 0x48
rohc_packet[ 31 ] = 0x43
rohc_packet[ 32 ] = 0x20
rohc_packet[ 33 ] = 0x77
rohc_packet[ 34 ] = 0x6f
rohc_packet[ 35 ] = 0x72
rohc_packet[ 36 ] = 0x6c
rohc_packet[ 37 ] = 0x64
rohc_packet[ 38 ] = 0x21

Thanks,
Wei

Wei Wang (eww012) said : #3

Hi Didier,

Do you mean, the first 3 bytes are the result by ROHC compressor?

Another question is, I commented out the uncompress profile and the original bytes are still there.

Thanks,
Weijian

Wei,

> However, the result is not right. Can you please take a look one more
> time? The original IP packet size is 38 (20 IP header bytes + 18 fake
> payload size) and the size after rohc_compress() is 39

The result is fully correct. Many compression schemes require to transmit more bits than the uncompressed data on the first packets. It may happen with ROHC too. Try compressing 10 packets in a row, the result will seem you more "right".

You are warned of that fact by the "simple_rohc_program". It prints the following conclusion at the very end of its execution: "The program ended successfully. The ROHC packet is larger than the IP packet (39 bytes versus 38 bytes). This is expected since we only compress one packet in this simple example. Keep in mind that ROHC is designed to compress streams of packets not one single packet."

> Do you mean, the first 3 bytes are the result by ROHC compressor?

When the ROHC Uncompressed profile is used, the ROHC compressor adds 3 bytes before the non-compressed packet. The first 3 bytes are generated by the ROHC compressor, the remaining bytes are a copy of the non-compressed packet. All of them compose the ROHC packet.

> Another question is, I commented out the uncompress profile
> and the original bytes are still there.

The IPv4 header bytes should not be present. Maybe are you confused by the payload bytes. Payload bytes will always be copied from the non-compressed packet to the ROHC packet since ROHC algorithms only apply to the protocol headers.

Regards,
Didier

Wei Wang (eww012) said : #5

Hi Didier,

I tried to concatenate 10 payloads together, started with the IP header in the example. I didn't see result looking more "right". Again, the result just repeat the payload bytes 10 times. The return size from rohc_compress() is 201, while the original packet size is 20 + 18*10 = 200.

I don't know where I didn't do correctly. Here are the steps I did:
(1) create compressor by rohc_alloc_compressor()
(2) activate profile(s) by rohc_activate_profile()
(3) prepare data packet
(4) call rohc_compress()

Sorry I keep bothering you with these dummy questions. And I don't want to waste space on your website. Can you please reply by email? My email address is <email address hidden>.

Thanks very much.
Wei

Wei Wang (eww012) said : #6

Hi Didier,

Sorry I made a mistake yesterday. Now I concatenate 10 packets together by repeating it 10 times, IP headers + payload + IP headers + payload ......

The result from roch_compress is 383 = 3 + (20 + 18)*10. Obviously, this is not correct.
 int ret_size = rohc_compress(compressor,
                      ip_packet, ip_packet_len*10,
                      rohc_packet, BUFFER_SIZE);

I wonder if or not I can compress 10 packets like that since their headers are identical and ROHC algorithm could think it is not right. Even I changed offset value, I still got return size of 383. Can you please give me a hint how to compress 10 packets at one time?

Thanks for your help.

Wei,

> I don't know where I didn't do correctly. Here are the steps I did:
> (1) create compressor by rohc_alloc_compressor()
> (2) activate profile(s) by rohc_activate_profile()
> (3) prepare data packet
> (4) call rohc_compress()

Don't concatenate IP headers, IP payloads or even full IP packets. Just compress one packet at a time. One IP packet results in one ROHC packet.

(1) create compressor by rohc_alloc_compressor()
(2) activate profile(s) by rohc_activate_profile()
(3) prepare IP packet #1
(4) call rohc_compress() with IP packet #1
(5) prepare IP packet #2
(6) call rohc_compress() with IP packet #2
(7) prepare IP packet #3
(8) call rohc_compress() with IP packet #3
...
(x-1) prepare IP packet #n
(x) call rohc_compress() with IP packet #n

I _strongly_ encourage you to read documentation (or ask an experimented person in your school/company) about network protocols in general, the IPv4 protocol, the UDP protocol, the RTP protocol, and of course the ROHC protocol. For the ROHC protocol, read at least the English wikipedia page [1] and the protocol overview on the project's wiki [2]. I will answer to any of your questions about the ROHC protocol, but I won't teach you generalities about network protocols and the IPv4/UDP/RTP protocols.

[1] https://en.wikipedia.org/wiki/ROHC
[2] http://rohc-lib.org/wiki/doku.php?id=rohc-protocol

> Sorry I keep bothering you with these dummy questions.
> And I don't want to waste space on your website. Can you
> please reply by email? My email address is SNIP.

The mailing list is for questions about the ROHC protocol and the ROHC library, so you're not at the wrong place. You're a beginner, so you're making mistakes and asking naive questions. Nothing surprising here. Improving your knowledge about network protocols should help you asking smarter questions.

As a last word, I avoid answering in private so that:
 - anyone on the list can answer you,
 - anyone on the list can learn from the answers of others,
 - the search engines put the answers in their databases.

Regards,
Didier

Wei Wang (eww012) said : #8

Thanks. I figured out this example.