Merge lp:~martin-lp/hipl/hipl_retransmissions into lp:hipl

Proposed by David Martin
Status: Merged
Merged at revision: 6206
Proposed branch: lp:~martin-lp/hipl/hipl_retransmissions
Merge into: lp:hipl
Diff against target: 650 lines (+249/-84)
9 files modified
hipd/hadb.c (+15/-6)
hipd/init.c (+31/-6)
hipd/input.c (+119/-5)
hipd/input.h (+6/-0)
hipd/maintenance.c (+39/-45)
hipd/netdev.c (+8/-5)
hipd/output.c (+13/-12)
lib/core/state.h (+7/-4)
modules/update/hipd/update.c (+11/-1)
To merge this branch: bzr merge lp:~martin-lp/hipl/hipl_retransmissions
Reviewer Review Type Date Requested Status
Diego Biurrun Abstain
Miika Komu Approve
Review via email: mp+87072@code.launchpad.net

This proposal supersedes a proposal from 2011-12-20.

Description of the change

Update:
Remarks on the code have been addressed in revisions 6224ff.

Previous description:
This branch fixes and improves the currently partially broken retransmissions in HIPL.

In short:
- buffer up to three retransmissions in simple round-robin style
 -> this does not affect regular management packets during BEX but makes it possible to retransmit the locators of the second UPDATE packet

- we remove buffered retransmission based on incoming packets from the peer
 -> hip_update_retransmissions() in input.c takes care of that
 -> for example an incoming R1 invalidates or acknowledges our buffered I1 retransmission
 -> it's the same for UPDATE packets. incoming U2 invalidates buffered U1, and U3 invalidates U2 respectively
 -> the rationale: if we do not get a response from the peer we can assume our or their packet was lost, so we retransmit. A received packet from the peer acts as acknowledgment and we remove the retransmissions. For this reason R2 and U3 packets do not get buffered for retransmission. Their retransmission is triggered by the peers retransmission of I2 or U2 respectively.

I have relatively thoroughly tested this and in the normal use case (no relay, opportunistic or what else we offer in special use cases) it works fine. Would be great if someone had a look at the other cases.

How to test these changes:
- decrease retransmission timeout define HIP_RETRANSMIT_WAIT in hipd.h (retransmission waiting time is still awfully long at the moment but out of scope of this branch to be changed)

- modify the packet loss defines in output.c (thanks Miika for the hint!)
 -> if it does not compile cast the random() call to uint64_t

To post a comment you must log in.
Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal

Seems good to me from the view point of functionality. May I ask few questions though:

1. Did you test that memory is deallocated (valgrind) - optional, but extra good karma if you do this :)
2. Does the scheme ignore retransmission of R1 messages (not really supposed to be resent)
3. Why to buffer to three messages?

Regarding to buffering, the state may change during retransmission and this causes the implementation to resend old messages in addition to new ones? If we're lucky, the peer will ignore UPDATE packets with old SPI numbers. However, the situation may be different in the BEX because there's no state.

A special (and supported) use case from base exchange: try to trigger the BEX simultaneously from both sides (i.e. break point both sides with gdb just after sending I1). I know the state machine can handle this but what happens to the retransmissions?

review: Needs Information
Revision history for this message
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal
Download full text (7.2 KiB)

 review needs-fixing

On Tue, Dec 20, 2011 at 11:43:26AM +0000, David Martin wrote:
> David Martin has proposed merging lp:~martin-lp/hipl/hipl_retransmissions into lp:hipl.
>
> --- hipd/hadb.c 2011-11-17 11:15:47 +0000
> +++ hipd/hadb.c 2011-12-20 11:41:33 +0000
> @@ -693,17 +693,25 @@
> }
>
> - entry->hip_msg_retrans.count = 0;
>
> /* Initialize module states */

You should remove an excess empty line here.

> --- hipd/input.c 2011-12-09 09:32:56 +0000
> +++ hipd/input.c 2011-12-20 11:41:33 +0000
> @@ -1877,3 +1873,117 @@
> +
> +/**
> + * Clear the given retransmission.
> + * i.e. set the remaining retransmissions to zero and zero the buffer.
> + *
> + * @param retrans The retransmission to be cleared.
> + */
> +void hip_clear_retransmission(struct hip_msg_retrans *const retrans)
> +{
> + if (!retrans) {
> + return;
> + }
> +
> + retrans->count = 0;
> + if (retrans->buf) {
> + memset(retrans->buf, 0, HIP_MAX_NETWORK_PACKET);

sizeof(retrans->buf) does not work?

> +/**
> + * Update our buffered retransmissions after receiving the given packet.
> + * This functions removes invalid retransmissions after a state change caused
> + * by a received packet. For example after successfully receiving and handling
> + * an I2 or R2 packet all our buffered packets are dropped.
> + *
> + * Call this function after successful handling of the incoming packet.
> + *
> + * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
> + * @param ha_state The host association state (RFC 5201, 4.4.1.)
> + * @param ctx The packet context of the incoming transmission.
> + *
> + * @return always 0
> + */

Why always return 0?

> +int hip_update_retransmissions(UNUSED const uint8_t packet_type,
> + UNUSED const enum hip_state ha_state,
> + struct hip_packet_context *const ctx)
> +{
> + struct hip_msg_retrans *retrans;
> +
> + HIP_ASSERT(ctx);
> + HIP_ASSERT(ctx->input_msg);
> +
> + /* When receiving an I1 there usually is no established state yet. */
> + if (!ctx->hadb_entry) {
> + return 0;
> + }
> +
> + for (unsigned int i = 0; i < HIP_RETRANSMIT_QUEUE_SIZE; i++) {
> + retrans = &ctx->hadb_entry->hip_msg_retrans[i];
> +
> + if (retrans->count == 0) {
> + continue;
> + }
> +
> + switch (hip_get_msg_type(ctx->input_msg)) {
> + case HIP_I1:
> + switch (hip_get_msg_type(retrans->buf)) {
> + case HIP_I1:
> + /* We only remove our sent I1s when we have got a greater HIT
> + * than the peer (ref. RFC 5201, 4.4.2). */
> + if (hip_hit_is_bigger(&ctx->hadb_entry->hit_our, &ctx->hadb_entry->hit_peer)) {
> + hip_clear_retransmission(retrans);
> + }
> + break;
> + }
> + break;

This nested switch statement for only one case looks pretty weird IMO.

> --- hipd/maintenance.c 2011-12-16 13:37:33 +0000
> +++ hipd/maintenance.c 2011-12-20 11:41:33 +0000
> @@ -92,53 +93,48 @@
> static int handle_retransmission(struct hip_hadb_state *entry,
> ...

Read more...

review: Needs Fixing
Revision history for this message
David Martin (martin-lp) wrote : Posted in a previous version of this proposal

Hi,

On Tue, Dec 20, 2011 at 6:50 PM, Miika Komu <email address hidden> wrote:
> Review: Needs Information
>
> 1. Did you test that memory is deallocated (valgrind) - optional, but extra good karma if you do this :)

Actually I did and it looks fine. There are only HIP_RETRANSMIT_QUEUE_SIZE - 1 more calls to calloc compared to before so there is not that much to go wrong. Static memory ftw.

> 2. Does the scheme ignore retransmission of R1 messages (not really supposed to be resent)

R1s don't get buffered (hip_send_r1() sets the retransmit flag to zero when sending the packet) so they are not retransmitted as well. I did not touch this or to answer your question: yes, they are ignored.

What I did change though is R2 and U3. They are now not retransmitted anymore as they don't get explicitly acknowledged. A retransmission is basically triggered by the peer when they send I2 / U2 again.

> 3. Why to buffer to three messages?

It's more than one to retransmit the locators during UPDATEs. And three is more or less arbitrarily chosen by me. Two did not seem worth the effort of looping through it and four seems not needed? How many locators are common when using HIPL? On my test setup it's always only two... This can easily be changed by changing HIP_RETRANSMIT_QUEUE_SIZE though.

> Regarding to buffering, the state may change during retransmission and this causes the implementation to resend old messages in addition to new ones? If we're lucky, the peer will ignore UPDATE packets with old SPI numbers. However, the situation may be different in the BEX because there's no state.

I'm not sure whether I fully get your question. You mean for example when you trigger three UPDATEs in a row you would have three retransmissions? Once one of the UPDATEs has been processed the peer would ignore the older retransmissions (check_update_freshness() would fail) and on our side the buffered retransmissions would be removed after receiving the U2 from the peer.

Can you trigger another BEX during BEX? Can I force hipd to send another I1 when I'm in state R1_SENT for example? I did not test this.

In general the behaviour during BEX is basically unchanged though in this branch. When a I2, R1, R2, CLOSE or CLOSE_ACK comes in from the peer we remove all our retransmissions. On the host side a retransmission does not cause a state change. Retransmissions are simply putting a packet again on the wire, not more.

> A special (and supported) use case from base exchange: try to trigger the BEX simultaneously from both sides (i.e. break point both sides with gdb just after sending I1). I know the state machine can handle this but what happens to the retransmissions?

Actually I did try this and when I let two machines ping each other virtually at the same time the BEX sort of gets stuck and neither side can get any traffic through (this is not specific to this branch as it is the same on trunk).

In theory this situation is dealt with though. When receiving an I1 the host with the greater HIT removes its own I1 retransmissions.

Revision history for this message
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal

On Wed, Dec 21, 2011 at 11:32:26AM +0100, Diego Biurrun wrote:
> On Tue, Dec 20, 2011 at 11:43:26AM +0000, David Martin wrote:
> > David Martin has proposed merging lp:~martin-lp/hipl/hipl_retransmissions into lp:hipl.
> >
> > --- hipd/output.c 2011-11-10 10:53:21 +0000
> > +++ hipd/output.c 2011-12-20 11:41:33 +0000
> > @@ -1118,22 +1118,25 @@
> > const struct hip_common *msg,
> > struct hip_hadb_state *entry)
> > {
> > - int len = hip_get_msg_total_len(msg);
> > + int len = hip_get_msg_total_len(msg);
> > + struct hip_msg_retrans *retrans;
> >
> > if (!entry) {
> > return 0;
> > }
> >
> > + retrans = &entry->hip_msg_retrans[entry->next_retrans_slot];
> > +
> > /* Not reusing the old entry as the new packet may have different length */
> > + memset(retrans->buf, 0, HIP_MAX_NETWORK_PACKET);
>
> see above
>
> > + memcpy(retrans->buf, msg, len);
> > + memcpy(&retrans->saddr, src_addr, sizeof(struct in6_addr));
> > + memcpy(&retrans->daddr, peer_addr, sizeof(struct in6_addr));

The comment I intended to add here was that this looks as if it can be
done by assignments instead of memcpy.

Diego

Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal

Hi,

On 22/12/11 00:22, Diego Biurrun wrote:
> On Wed, Dec 21, 2011 at 11:32:26AM +0100, Diego Biurrun wrote:
>> On Tue, Dec 20, 2011 at 11:43:26AM +0000, David Martin wrote:
>>> David Martin has proposed merging lp:~martin-lp/hipl/hipl_retransmissions into lp:hipl.
>>>
>>> --- hipd/output.c 2011-11-10 10:53:21 +0000
>>> +++ hipd/output.c 2011-12-20 11:41:33 +0000
>>> @@ -1118,22 +1118,25 @@
>>> const struct hip_common *msg,
>>> struct hip_hadb_state *entry)
>>> {
>>> - int len = hip_get_msg_total_len(msg);
>>> + int len = hip_get_msg_total_len(msg);
>>> + struct hip_msg_retrans *retrans;
>>>
>>> if (!entry) {
>>> return 0;
>>> }
>>>
>>> + retrans =&entry->hip_msg_retrans[entry->next_retrans_slot];
>>> +
>>> /* Not reusing the old entry as the new packet may have different length */
>>> + memset(retrans->buf, 0, HIP_MAX_NETWORK_PACKET);
>>
>> see above
>>
>>> + memcpy(retrans->buf, msg, len);
>>> + memcpy(&retrans->saddr, src_addr, sizeof(struct in6_addr));
>>> + memcpy(&retrans->daddr, peer_addr, sizeof(struct in6_addr));
>
> The comment I intended to add here was that this looks as if it can be
> done by assignments instead of memcpy.

if you refer to IPv6 addresses, they have to be copied (no such thing as
128-bit integer). Anyway, the most elegant way is to use
ipv6_addr_copy() instead of memcpy().

Revision history for this message
David Martin (martin-lp) wrote : Posted in a previous version of this proposal
Download full text (8.6 KiB)

Hi,

On Wed, Dec 21, 2011 at 11:32 AM, Diego Biurrun <email address hidden> wrote:
> review needs-fixing
>
> On Tue, Dec 20, 2011 at 11:43:26AM +0000, David Martin wrote:
>> David Martin has proposed merging lp:~martin-lp/hipl/hipl_retransmissions into lp:hipl.
>>
>> --- hipd/hadb.c 2011-11-17 11:15:47 +0000
>> +++ hipd/hadb.c 2011-12-20 11:41:33 +0000
>> @@ -693,17 +693,25 @@
>> }
>>
>> - entry->hip_msg_retrans.count = 0;
>>
>> /* Initialize module states */
>
> You should remove an excess empty line here.

fixed.

>> --- hipd/input.c 2011-12-09 09:32:56 +0000
>> +++ hipd/input.c 2011-12-20 11:41:33 +0000
>> @@ -1877,3 +1873,117 @@
>> +
>> +/**
>> + * Clear the given retransmission.
>> + * i.e. set the remaining retransmissions to zero and zero the buffer.
>> + *
>> + * @param retrans The retransmission to be cleared.
>> + */
>> +void hip_clear_retransmission(struct hip_msg_retrans *const retrans)
>> +{
>> + if (!retrans) {
>> + return;
>> + }
>> +
>> + retrans->count = 0;
>> + if (retrans->buf) {
>> + memset(retrans->buf, 0, HIP_MAX_NETWORK_PACKET);
>
> sizeof(retrans->buf) does not work?

Nope. It's just a pointer so that would not make much sense. But even referencing the struct does not seem right:

debug(hipd/input.c:1891@hip_clear_retransmission): HIP_MAX_NETWORK_PACKET: 2048
debug(hipd/input.c:1892@hip_clear_retransmission): sizeof(retrans->buf): 8
debug(hipd/input.c:1893@hip_clear_retransmission): sizeof(*retrans->buf): 40

>> +/**
>> + * Update our buffered retransmissions after receiving the given packet.
>> + * This functions removes invalid retransmissions after a state change caused
>> + * by a received packet. For example after successfully receiving and handling
>> + * an I2 or R2 packet all our buffered packets are dropped.
>> + *
>> + * Call this function after successful handling of the incoming packet.
>> + *
>> + * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
>> + * @param ha_state The host association state (RFC 5201, 4.4.1.)
>> + * @param ctx The packet context of the incoming transmission.
>> + *
>> + * @return always 0
>> + */
>
> Why always return 0?

Nothing unforeseen may happen that I deem important enough to break the handling of packets. I would make it void but the handle functions have to return an int.

>> +int hip_update_retransmissions(UNUSED const uint8_t packet_type,
>> + UNUSED const enum hip_state ha_state,
>> + struct hip_packet_context *const ctx)
>> +{
>> + struct hip_msg_retrans *retrans;
>> +
>> + HIP_ASSERT(ctx);
>> + HIP_ASSERT(ctx->input_msg);
>> +
>> + /* When receiving an I1 there usually is no established state yet. */
>> + if (!ctx->hadb_entry) {
>> + return 0;
>> + }
>> +
>> + for (unsigned int i = 0; i < HIP_RETRANSMIT_QUEUE_SIZE; i++) {
>> + retrans = &ctx->hadb_entry->hip_msg_retrans[i];
>> +
>> + if (retrans->count == 0) {
>> + continue;
>> + }
>> +
>> + switch (hip_get_msg_type(ctx->input_msg)) {
>> + case HIP_I1:
>> + switch (hip_get_msg_type...

Read more...

Revision history for this message
David Martin (martin-lp) wrote : Posted in a previous version of this proposal

Hi,

On Thu, Dec 22, 2011 at 8:42 AM, Miika Komu <email address hidden> wrote:
> On 22/12/11 00:22, Diego Biurrun wrote:
>>
>> On Wed, Dec 21, 2011 at 11:32:26AM +0100, Diego Biurrun wrote:
>>>
>>> On Tue, Dec 20, 2011 at 11:43:26AM +0000, David Martin wrote:
>>>>
>>>> David Martin has proposed merging
>>>> lp:~martin-lp/hipl/hipl_retransmissions into lp:hipl.
>>>>
>>>> --- hipd/output.c 2011-11-10 10:53:21 +0000
>>>> +++ hipd/output.c 2011-12-20 11:41:33 +0000
>>>> @@ -1118,22 +1118,25 @@
>>>> const struct hip_common *msg,
>>>> struct hip_hadb_state *entry)
>>>> {
>>>> - int len = hip_get_msg_total_len(msg);
>>>> + int len = hip_get_msg_total_len(msg);
>>>> + struct hip_msg_retrans *retrans;
>>>>
>>>> if (!entry) {
>>>> return 0;
>>>> }
>>>>
>>>> + retrans =&entry->hip_msg_retrans[entry->next_retrans_slot];
>>>>
>>>> +
>>>> /* Not reusing the old entry as the new packet may have different
>>>> length */
>>>> + memset(retrans->buf, 0, HIP_MAX_NETWORK_PACKET);
>>>
>>>
>>> see above
>>>
>>>> + memcpy(retrans->buf, msg, len);
>>>> + memcpy(&retrans->saddr, src_addr, sizeof(struct in6_addr));
>>>> + memcpy(&retrans->daddr, peer_addr, sizeof(struct in6_addr));
>>
>>
>> The comment I intended to add here was that this looks as if it can be
>> done by assignments instead of memcpy.
>
>
> if you refer to IPv6 addresses, they have to be copied (no such thing as
> 128-bit integer). Anyway, the most elegant way is to use ipv6_addr_copy()
> instead of memcpy().

I don't think you can assign the buffer as they are independent. The retrans buffer slots are allocated at startup and the message comes wherever the caller allocates it from.

I've removed the needless variable indirection of the int len though and replaced the address memcpy() calls with ipv6_addr_copy().

Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal
Download full text (4.1 KiB)

Hi,

On 21/12/11 12:46, David Martin wrote:
> Hi,
>
> On Tue, Dec 20, 2011 at 6:50 PM, Miika Komu<email address hidden> wrote:
>> Review: Needs Information
>>
>> 1. Did you test that memory is deallocated (valgrind) - optional,
>> but extra good karma if you do this :)
>
> Actually I did and it looks fine. There are only
> HIP_RETRANSMIT_QUEUE_SIZE - 1 more calls to calloc compared to before
> so there is not that much to go wrong. Static memory ftw.
>
>> 2. Does the scheme ignore retransmission of R1 messages (not really
>> supposed to be resent)
>
> R1s don't get buffered (hip_send_r1() sets the retransmit flag to
> zero when sending the packet) so they are not retransmitted as well.
> I did not touch this or to answer your question: yes, they are
> ignored.
>
> What I did change though is R2 and U3. They are now not retransmitted
> anymore as they don't get explicitly acknowledged. A retransmission
> is basically triggered by the peer when they send I2 / U2 again.
>
>
>> 3. Why to buffer to three messages?
>
> It's more than one to retransmit the locators during UPDATEs. And
> three is more or less arbitrarily chosen by me. Two did not seem
> worth the effort of looping through it and four seems not needed? How
> many locators are common when using HIPL? On my test setup it's
> always only two... This can easily be changed by changing
> HIP_RETRANSMIT_QUEUE_SIZE though.

maybe I failed to understand something or should dig into the code
better. Are you saying that a buffered packet is a) retransmitted three
times or b) three packets can be queued?

Option a) makes sense, option b) doesn't make sense because the
retransmitted packets are identical (in most cases, see below).

>> Regarding to buffering, the state may change during retransmission
>> and this causes the implementation to resend old messages in
>> addition to new ones? If we're lucky, the peer will ignore UPDATE
>> packets with old SPI numbers. However, the situation may be
>> different in the BEX because there's no state.
>
> I'm not sure whether I fully get your question. You mean for example
> when you trigger three UPDATEs in a row you would have three
> retransmissions? Once one of the UPDATEs has been processed the peer
> would ignore the older retransmissions (check_update_freshness()
> would fail) and on our side the buffered retransmissions would be
> removed after receiving the U2 from the peer.

Regarding to option b), the packets can be different e.g. with UPDATEs.
It occurs that a host obtains new locators every now and then. If the
host has a queue of length of more than two, then it keeps sending an
old buffered set of locators in addition to the new set. While this is
not a big issue, it's completely unnecessary and should be avoided IMHO.
The easiest way to avoid this is to have queue of size one.

> Can you trigger another BEX during BEX? Can I force hipd to send
> another I1 when I'm in state R1_SENT for example? I did not test
> this.

No.

> In general the behaviour during BEX is basically unchanged though in
> this branch. When a I2, R1, R2, CLOSE or CLOSE_ACK comes in from the
> peer we remove all our retransmissions. On the host side a
> retransmissi...

Read more...

Revision history for this message
Diego Biurrun (diego-biurrun) wrote : Posted in a previous version of this proposal
Download full text (5.9 KiB)

On Thu, Dec 22, 2011 at 10:05:21AM +0000, David Martin wrote:
> On Wed, Dec 21, 2011 at 11:32 AM, Diego Biurrun <email address hidden> wrote:
> > On Tue, Dec 20, 2011 at 11:43:26AM +0000, David Martin wrote:
> >> David Martin has proposed merging lp:~martin-lp/hipl/hipl_retransmissions into lp:hipl.
> >>
> >> --- hipd/input.c 2011-12-09 09:32:56 +0000
> >> +++ hipd/input.c 2011-12-20 11:41:33 +0000
> >> @@ -1877,3 +1873,117 @@
> >> +
> >> +/**
> >> + * Clear the given retransmission.
> >> + * i.e. set the remaining retransmissions to zero and zero the buffer.
> >> + *
> >> + * @param retrans The retransmission to be cleared.
> >> + */
> >> +void hip_clear_retransmission(struct hip_msg_retrans *const retrans)
> >> +{
> >> + if (!retrans) {
> >> + return;
> >> + }
> >> +
> >> + retrans->count = 0;
> >> + if (retrans->buf) {
> >> + memset(retrans->buf, 0, HIP_MAX_NETWORK_PACKET);
> >
> > sizeof(retrans->buf) does not work?
>
> Nope. It's just a pointer so that would not make much sense.

Sorry, sizeof(*retrans->buf) of course, I make this mistake all the time :-/

> But even referencing the struct does not seem right:
>
> debug(hipd/input.c:1891@hip_clear_retransmission): HIP_MAX_NETWORK_PACKET: 2048
> debug(hipd/input.c:1892@hip_clear_retransmission): sizeof(retrans->buf): 8
> debug(hipd/input.c:1893@hip_clear_retransmission): sizeof(*retrans->buf): 40

buf is a pointer to struct hip_common, which is

  struct hip_common {
      uint8_t payload_proto;
      uint8_t payload_len;
      uint8_t type_hdr;
      uint8_t ver_res;
      uint16_t checksum;
      uint16_t control;
      struct in6_addr hits; /**< Sender HIT */
      struct in6_addr hitr; /**< Receiver HIT */
  } __attribute__((packed));

so I guess the 40 bytes is about right.

So why 2048? It looks as though you are zeroing way beyond the field
you intend to initialize ...

> >> +/**
> >> + * Update our buffered retransmissions after receiving the given packet.
> >> + * This functions removes invalid retransmissions after a state change caused
> >> + * by a received packet. For example after successfully receiving and handling
> >> + * an I2 or R2 packet all our buffered packets are dropped.
> >> + *
> >> + * Call this function after successful handling of the incoming packet.
> >> + *
> >> + * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
> >> + * @param ha_state The host association state (RFC 5201, 4.4.1.)
> >> + * @param ctx The packet context of the incoming transmission.
> >> + *
> >> + * @return always 0
> >> + */
> >
> > Why always return 0?
>
> Nothing unforeseen may happen that I deem important enough to break
> the handling of packets. I would make it void but the handle functions
> have to return an int.

OK, a short comment explaining this would be nice.

> >> --- hipd/maintenance.c 2011-12-16 13:37:33 +0000
> >> +++ hipd/maintenance.c 2011-12-20 11:41:33 +0000
> >> @@ -92,53 +93,48 @@
> >> static int handle_retransmission(struct hip_hadb_state *entry,
> >> void *current_time)
> >> {
> >> + ...

Read more...

Revision history for this message
David Martin (martin-lp) wrote : Posted in a previous version of this proposal
Download full text (3.5 KiB)

Hi,

On Thu, Dec 22, 2011 at 1:31 PM, Diego Biurrun <email address hidden> wrote:
> On Thu, Dec 22, 2011 at 10:05:21AM +0000, David Martin wrote:
>> On Wed, Dec 21, 2011 at 11:32 AM, Diego Biurrun <email address hidden> wrote:
>> > On Tue, Dec 20, 2011 at 11:43:26AM +0000, David Martin wrote:
>> >> David Martin has proposed merging lp:~martin-lp/hipl/hipl_retransmissions into lp:hipl.
>> >>
>> >> --- hipd/input.c 2011-12-09 09:32:56 +0000
>> >> +++ hipd/input.c 2011-12-20 11:41:33 +0000
>> >> @@ -1877,3 +1873,117 @@
>> >> +
>> >> +/**
>> >> + * Clear the given retransmission.
>> >> + * i.e. set the remaining retransmissions to zero and zero the buffer.
>> >> + *
>> >> + * @param retrans The retransmission to be cleared.
>> >> + */
>> >> +void hip_clear_retransmission(struct hip_msg_retrans *const retrans)
>> >> +{
>> >> + if (!retrans) {
>> >> + return;
>> >> + }
>> >> +
>> >> + retrans->count = 0;
>> >> + if (retrans->buf) {
>> >> + memset(retrans->buf, 0, HIP_MAX_NETWORK_PACKET);
>> >
>> > sizeof(retrans->buf) does not work?
>>
>> Nope. It's just a pointer so that would not make much sense.
>
> Sorry, sizeof(*retrans->buf) of course, I make this mistake all the time :-/
>
>> But even referencing the struct does not seem right:
>>
>> debug(hipd/input.c:1891@hip_clear_retransmission): HIP_MAX_NETWORK_PACKET: 2048
>> debug(hipd/input.c:1892@hip_clear_retransmission): sizeof(retrans->buf): 8
>> debug(hipd/input.c:1893@hip_clear_retransmission): sizeof(*retrans->buf): 40
>
> buf is a pointer to struct hip_common, which is
>
> struct hip_common {
> uint8_t payload_proto;
> uint8_t payload_len;
> uint8_t type_hdr;
> uint8_t ver_res;
> uint16_t checksum;
> uint16_t control;
> struct in6_addr hits; /**< Sender HIT */
> struct in6_addr hitr; /**< Receiver HIT */
> } __attribute__((packed));
>
> so I guess the 40 bytes is about right.
>
> So why 2048? It looks as though you are zeroing way beyond the field
> you intend to initialize ...

You are right and wrong. 40 bytes is wrong as this would only be the size of the message header. You have to keep in mind that there's payload as well. You are right as 2048 is the maximum size and a sort of pessimistic approach. I've changed it so that it zeros only the actual message size. The queuing function uses hip_get_msg_total_len() to determine how many bytes to copy into the buffer. I'm using the same now to determine how many bytes to zero. They are the only two functions actually changing the buffer so this is good now.

>> >> +/**
>> >> + * Update our buffered retransmissions after receiving the given packet.
>> >> + * This functions removes invalid retransmissions after a state change caused
>> >> + * by a received packet. For example after successfully receiving and handling
>> >> + * an I2 or R2 packet all our buffered packets are dropped.
>> >> + *
>> >> + * Call this function after successful handling of the incoming packet.
>> >> + *
>> >> + * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
>> >> + * @param ha_state The host association sta...

Read more...

Revision history for this message
David Martin (martin-lp) wrote : Posted in a previous version of this proposal
Download full text (3.7 KiB)

Hi,

On Thu, Dec 22, 2011 at 11:45 AM, Miika Komu <email address hidden> wrote:
> On 21/12/11 12:46, David Martin wrote:
>> On Tue, Dec 20, 2011 at 6:50 PM, Miika Komu<email address hidden> wrote:

>>> 3. Why to buffer to three messages?
>>
>>
>> It's more than one to retransmit the locators during UPDATEs. And
>> three is more or less arbitrarily chosen by me. Two did not seem
>> worth the effort of looping through it and four seems not needed? How
>> many locators are common when using HIPL? On my test setup it's
>> always only two... This can easily be changed by changing
>> HIP_RETRANSMIT_QUEUE_SIZE though.
>
>
> maybe I failed to understand something or should dig into the code better.
> Are you saying that a buffered packet is a) retransmitted three times or b)
> three packets can be queued?
>
> Option a) makes sense, option b) doesn't make sense because the
> retransmitted packets are identical (in most cases, see below).

We are doing option b) in this branch. Well, are they identical? The destination of the buffered U2 packets differ because of the locators so this is not true, no?

>>> Regarding to buffering, the state may change during retransmission
>>> and this causes the implementation to resend old messages in
>>> addition to new ones? If we're lucky, the peer will ignore UPDATE
>>> packets with old SPI numbers. However, the situation may be
>>> different in the BEX because there's no state.
>>
>>
>> I'm not sure whether I fully get your question. You mean for example
>> when you trigger three UPDATEs in a row you would have three
>> retransmissions? Once one of the UPDATEs has been processed the peer
>> would ignore the older retransmissions (check_update_freshness()
>> would fail) and on our side the buffered retransmissions would be
>> removed after receiving the U2 from the peer.
>
>
> Regarding to option b), the packets can be different e.g. with UPDATEs. It
> occurs that a host obtains new locators every now and then. If the host has
> a queue of length of more than two, then it keeps sending an old buffered
> set of locators in addition to the new set. While this is not a big issue,
> it's completely unnecessary and should be avoided IMHO. The easiest way to
> avoid this is to have queue of size one.

Setting the queue to size to one would completely defeat its point though. How often does such a locator change happen? I guess in theory it may happen that an UPDATE is triggered and lost, the host obtains a new locator and another UPDATE is triggered which is lost again. Then you would actually retransmit both UPDATEs with different locators.
A solution may be to remove older buffered U1 packets when a new UPDATE is triggered. I may change that if necessary or desired.

>> Can you trigger another BEX during BEX? Can I force hipd to send
>> another I1 when I'm in state R1_SENT for example? I did not test
>> this.
>
>
> No.

Ok, so we do not have a problem here.

>>> A special (and supported) use case from base exchange: try to
>>> trigger the BEX simultaneously from both sides (i.e. break point
>>> both sides with gdb just after sending I1). I know the state
>>> machine can handle this but what happens to the retransmissions?
>>...

Read more...

Revision history for this message
Miika Komu (miika-iki) wrote : Posted in a previous version of this proposal
Download full text (4.4 KiB)

Hi,

On 12/29/2011 01:01 PM, David Martin wrote:
> Hi,
>
> On Thu, Dec 22, 2011 at 11:45 AM, Miika Komu<email address hidden>
> wrote:
>> On 21/12/11 12:46, David Martin wrote:
>>> On Tue, Dec 20, 2011 at 6:50 PM, Miika Komu<email address hidden>
>>> wrote:
>
>>>> 3. Why to buffer to three messages?
>>>
>>>
>>> It's more than one to retransmit the locators during UPDATEs.
>>> And three is more or less arbitrarily chosen by me. Two did not
>>> seem worth the effort of looping through it and four seems not
>>> needed? How many locators are common when using HIPL? On my test
>>> setup it's always only two... This can easily be changed by
>>> changing HIP_RETRANSMIT_QUEUE_SIZE though.
>>
>>
>> maybe I failed to understand something or should dig into the code
>> better. Are you saying that a buffered packet is a) retransmitted
>> three times or b) three packets can be queued?
>>
>> Option a) makes sense, option b) doesn't make sense because the
>> retransmitted packets are identical (in most cases, see below).
>
> We are doing option b) in this branch. Well, are they identical? The
> destination of the buffered U2 packets differ because of the locators
> so this is not true, no?

the retransmitted packages are different only in exceptional
circumstances. Similarly, the destination is usually the same because
there is one retransmission queue per host association - right?

Note: the destination can actually change with the shotgun extension
because it sends an UPDATE to all known peer addresses.

>>>> Regarding to buffering, the state may change during
>>>> retransmission and this causes the implementation to resend old
>>>> messages in addition to new ones? If we're lucky, the peer will
>>>> ignore UPDATE packets with old SPI numbers. However, the
>>>> situation may be different in the BEX because there's no
>>>> state.
>>>
>>>
>>> I'm not sure whether I fully get your question. You mean for
>>> example when you trigger three UPDATEs in a row you would have
>>> three retransmissions? Once one of the UPDATEs has been processed
>>> the peer would ignore the older retransmissions
>>> (check_update_freshness() would fail) and on our side the
>>> buffered retransmissions would be removed after receiving the U2
>>> from the peer.
>>
>>
>> Regarding to option b), the packets can be different e.g. with
>> UPDATEs. It occurs that a host obtains new locators every now and
>> then. If the host has a queue of length of more than two, then it
>> keeps sending an old buffered set of locators in addition to the
>> new set. While this is not a big issue, it's completely unnecessary
>> and should be avoided IMHO. The easiest way to avoid this is to
>> have queue of size one.
>
> Setting the queue to size to one would completely defeat its point
> though.

What is the point of having a queue size of more than one actually? Or
is that that the buffer size determines the number of retransmissions?

> How often does such a locator change happen?

Seldom by default because hipd reacts to locator changes with an
intended delay to accumulate the changes.

> I guess in
> theory it may happen that an UPDATE is triggered and lost, the host
> obtains a new locator and another UPDA...

Read more...

Revision history for this message
David Martin (martin-lp) wrote :
Download full text (5.2 KiB)

Hey,

On Thu, Dec 29, 2011 at 12:29 PM, Miika Komu <email address hidden> wrote:
> On 12/29/2011 01:01 PM, David Martin wrote:
>> On Thu, Dec 22, 2011 at 11:45 AM, Miika Komu<email address hidden>
>>> On 21/12/11 12:46, David Martin wrote:
>>>> On Tue, Dec 20, 2011 at 6:50 PM, Miika Komu<email address hidden>

>>>>> 3. Why to buffer to three messages?
>>>>
>>>> It's more than one to retransmit the locators during UPDATEs.
>>>> And three is more or less arbitrarily chosen by me. Two did not
>>>> seem worth the effort of looping through it and four seems not
>>>> needed? How many locators are common when using HIPL? On my test
>>>> setup it's always only two... This can easily be changed by
>>>> changing HIP_RETRANSMIT_QUEUE_SIZE though.
>>>
>>> maybe I failed to understand something or should dig into the code
>>> better. Are you saying that a buffered packet is a) retransmitted
>>> three times or b) three packets can be queued?
>>>
>>> Option a) makes sense, option b) doesn't make sense because the
>>> retransmitted packets are identical (in most cases, see below).
>>
>>
>> We are doing option b) in this branch. Well, are they identical? The
>> destination of the buffered U2 packets differ because of the locators
>> so this is not true, no?
>
> the retransmitted packages are different only in exceptional
> circumstances. Similarly, the destination is usually the same because
> there is one retransmission queue per host association - right?

I'm not sure whether we are talking at cross-purposes right now. :) In principle it's quite simple:
Yes, retransmissions are handled on a per host association basis. At the moment in trunk we have got a single maximum message sized buffer for each host association. When we send a message (which is supposed to be retransmitted when it does not reach its destination) it gets copied to this buffer. Every subsequent message gets copied into the same buffer overwriting the previous one. This is fine for BEX as packets are send on their own and we do not care about previous ones. As far as I understand it it is different for UPDATEs. The first UPDATE packet has got a list of locators. The second UPDATE packet from the peer is send to all of these locators. In the case we send to 3 locators, the first and second transmission would never be retransmitted as they get overwritten by the subsequent ones.

Now what this branch does is instead of having at max a single message per HA buffered we now can buffer up to three (set by a #define and open for discussion which value is best) messages per HA. This means that in case of the second UPDATE packet all transmissions to the different locators are retransmitted and not just the last one. This change for UPDATE retransmissions is the real benefit of increasing the queue size. It does not make a difference for normal BEX.

> Note: the destination can actually change with the shotgun extension because
> it sends an UPDATE to all known peer addresses.

If I see it right in hip_send_pkt() in output.c all packets get transmitted to all known addresses when the shotgun extension is used. This would benefit of a greater queue size as well then as then all packets to the different addresses...

Read more...

Revision history for this message
Miika Komu (miika-iki) wrote :

Thanks, I understood now. Good work!

review: Approve
Revision history for this message
Diego Biurrun (diego-biurrun) wrote :
Download full text (3.3 KiB)

 review abstain

I leave the decision to Miika, who still had some concerns.
Below are some minor issues I noticed; at least the typo
should be addressed before merging.

On Thu, Dec 29, 2011 at 11:15:31AM +0000, David Martin wrote:
> David Martin has proposed merging lp:~martin-lp/hipl/hipl_retransmissions into lp:hipl.
>
> Requested reviews:
> Diego Biurrun (diego-biurrun)
> Miika Komu (miika-iki)
>
> --- hipd/input.c 2011-12-09 09:32:56 +0000
> +++ hipd/input.c 2011-12-29 11:14:24 +0000
> @@ -1877,3 +1873,121 @@
>
> +/**
> + * Update our buffered retransmissions after receiving the given packet.
> + * This functions removes invalid retransmissions after a state change caused
> + * by a received packet. For example after successfully receiving and handling
> + * an I2 or R2 packet all our buffered packets are dropped.
> + *
> + * Call this function after successful handling of the incoming packet.
> + *
> + * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
> + * @param ha_state The host association state (RFC 5201, 4.4.1.)
> + * @param ctx The packet context of the incoming transmission.
> + *
> + * @return Always 0. Nothing onforeseen may happen here which is important

_u_nforeseen

> --- hipd/maintenance.c 2011-12-21 10:54:26 +0000
> +++ hipd/maintenance.c 2011-12-29 11:14:24 +0000
> @@ -89,55 +90,50 @@
> +static int handle_retransmissions(struct hip_hadb_state *entry,
> + void *current_time)
> {
> +
> + for (i = 0; i < HIP_RETRANSMIT_QUEUE_SIZE; i++) {
> + retrans = &entry->hip_msg_retrans[(entry->next_retrans_slot + i) %
> + HIP_RETRANSMIT_QUEUE_SIZE];
> +
> + /* check if the last transmission was at least RETRANSMIT_WAIT seconds ago */
> + if (*now - HIP_RETRANSMIT_WAIT > retrans->last_transmit) {
> + if (retrans->count > 0) {
> + /* @todo: verify that this works over slow ADSL line */
> + if (hip_send_pkt(&retrans->saddr,
> + &retrans->daddr,
> + entry->nat_mode ? hip_get_local_nat_udp_port() : 0,
> + entry->peer_udp_port,
> + retrans->buf,
> + entry, 0) < 0) {
> + HIP_ERROR("Failed to retransmit packet of type %d.\n",
> + hip_get_msg_type(retrans->buf));
> + err = -1;
> + }
> +
> + /* Set entry state, if previous state was unassociated
> + * and type is I1. */
> + if (!err && hip_get_msg_type(retrans->buf) == HIP_I1 &&
> + entry->state == HIP_STATE_UNASSOCIATED) {
> + HIP_DEBUG("Resent I1 succcesfully\n");
> + entry->state = HIP_STATE_I1_SENT;
> + }

Instead of testing err you could move this into the previous if-block.
That would read more natural to me.

> + retrans->count--;
> + time(&retrans->last_transmit);
> } else {
> + if (hip_get_m...

Read more...

review: Abstain
6234. By David Martin

Fix typo in hip_update_retransmissions() doxygen documentation.

6235. By David Martin

Make if-conditions in handle_retransmissions() more reasonable.

Do not check for the err value twice and use else if when there is only
a single if condition in the else case.

Revision history for this message
David Martin (martin-lp) wrote :

I've fixed the two issues mentioned by Diego in revisions 6234f. Should I start another review or is it good as is?

Revision history for this message
Miika Komu (miika-iki) wrote :

In my opinion, go ahead and merge.

Revision history for this message
David Martin (martin-lp) wrote :

Ok, done.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'hipd/hadb.c'
--- hipd/hadb.c 2011-12-28 15:52:14 +0000
+++ hipd/hadb.c 2011-12-29 15:06:25 +0000
@@ -693,17 +693,24 @@
693 get_random_bytes(&entry->spi_inbound_current,693 get_random_bytes(&entry->spi_inbound_current,
694 sizeof(entry->spi_inbound_current));694 sizeof(entry->spi_inbound_current));
695695
696 if (!(entry->hip_msg_retrans.buf = calloc(1, HIP_MAX_NETWORK_PACKET))) {696 entry->next_retrans_slot = 0;
697 return -ENOMEM;697 for (unsigned int i = 0; i < HIP_RETRANSMIT_QUEUE_SIZE; i++) {
698 if (!(entry->hip_msg_retrans[i].buf = calloc(1, HIP_MAX_NETWORK_PACKET))) {
699 for (unsigned int j = 0; j < i; j++) {
700 free(entry->hip_msg_retrans[j].buf);
701 }
702 return -ENOMEM;
703 }
704 entry->hip_msg_retrans[i].count = 0;
698 }705 }
699706
700 entry->hip_msg_retrans.count = 0;
701
702 /* Initialize module states */707 /* Initialize module states */
703 entry->hip_modular_state = lmod_init_state();708 entry->hip_modular_state = lmod_init_state();
704 if (entry->hip_modular_state == NULL) {709 if (entry->hip_modular_state == NULL) {
705 HIP_ERROR("Failed to initialize modular state.\n");710 HIP_ERROR("Failed to initialize modular state.\n");
706 free(entry->hip_msg_retrans.buf);711 for (unsigned int i = 0; i < HIP_RETRANSMIT_QUEUE_SIZE; i++) {
712 free(entry->hip_msg_retrans[i].buf);
713 }
707 return -1;714 return -1;
708 }715 }
709 lmod_init_state_items(entry->hip_modular_state);716 lmod_init_state_items(entry->hip_modular_state);
@@ -823,7 +830,9 @@
823 /* Delete SAs */830 /* Delete SAs */
824831
825 free(ha->dh_shared_key);832 free(ha->dh_shared_key);
826 free(ha->hip_msg_retrans.buf);833 for (i = 0; i < HIP_RETRANSMIT_QUEUE_SIZE; i++) {
834 free(ha->hip_msg_retrans[i].buf);
835 }
827 if (ha->peer_pub) {836 if (ha->peer_pub) {
828 switch (hip_get_host_id_algo(ha->peer_pub)) {837 switch (hip_get_host_id_algo(ha->peer_pub)) {
829 case HIP_HI_RSA:838 case HIP_HI_RSA:
830839
=== modified file 'hipd/init.c'
--- hipd/init.c 2011-12-12 14:30:43 +0000
+++ hipd/init.c 2011-12-29 15:06:25 +0000
@@ -561,31 +561,40 @@
561561
562 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_check_i1, 20000);562 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_check_i1, 20000);
563 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_handle_i1, 30000);563 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_handle_i1, 30000);
564 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_update_retransmissions, 35000);
564 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_send_r1, 40000);565 hip_register_handle_function(HIP_I1, HIP_STATE_UNASSOCIATED, &hip_send_r1, 40000);
565 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_check_i1, 20000);566 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_check_i1, 20000);
566 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_handle_i1, 30000);567 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_handle_i1, 30000);
568 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_update_retransmissions, 35000);
567 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_send_r1, 40000);569 hip_register_handle_function(HIP_I1, HIP_STATE_I1_SENT, &hip_send_r1, 40000);
568 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_check_i1, 20000);570 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_check_i1, 20000);
569 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_handle_i1, 30000);571 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_handle_i1, 30000);
572 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_update_retransmissions, 35000);
570 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_send_r1, 40000);573 hip_register_handle_function(HIP_I1, HIP_STATE_I2_SENT, &hip_send_r1, 40000);
571 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_check_i1, 20000);574 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_check_i1, 20000);
572 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_handle_i1, 30000);575 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_handle_i1, 30000);
576 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_update_retransmissions, 35000);
573 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_send_r1, 40000);577 hip_register_handle_function(HIP_I1, HIP_STATE_R2_SENT, &hip_send_r1, 40000);
574 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_check_i1, 20000);578 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_check_i1, 20000);
575 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_handle_i1, 30000);579 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_handle_i1, 30000);
580 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_update_retransmissions, 35000);
576 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_send_r1, 40000);581 hip_register_handle_function(HIP_I1, HIP_STATE_ESTABLISHED, &hip_send_r1, 40000);
577 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_check_i1, 20000);582 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_check_i1, 20000);
578 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_handle_i1, 30000);583 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_handle_i1, 30000);
584 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_update_retransmissions, 35000);
579 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_send_r1, 40000);585 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSING, &hip_send_r1, 40000);
580 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_check_i1, 20000);586 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_check_i1, 20000);
581 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_handle_i1, 30000);587 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_handle_i1, 30000);
588 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_update_retransmissions, 35000);
582 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_send_r1, 40000);589 hip_register_handle_function(HIP_I1, HIP_STATE_CLOSED, &hip_send_r1, 40000);
583 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_check_i1, 20000);590 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_check_i1, 20000);
584 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_handle_i1, 30000);591 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_handle_i1, 30000);
592 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_update_retransmissions, 35000);
585 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_send_r1, 40000);593 hip_register_handle_function(HIP_I1, HIP_STATE_NONE, &hip_send_r1, 40000);
586594
587 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_check_i2, 20000);595 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_check_i2, 20000);
588 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_handle_i2, 30000);596 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_handle_i2, 30000);
597 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_update_retransmissions, 30250);
589 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_setup_ipsec_sa, 30500);598 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_setup_ipsec_sa, 30500);
590 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_create_r2, 40000);599 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_create_r2, 40000);
591 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_add_rvs_reg_from, 41000);600 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_add_rvs_reg_from, 41000);
@@ -594,6 +603,7 @@
594 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_send_r2, 50000);603 hip_register_handle_function(HIP_I2, HIP_STATE_UNASSOCIATED, &hip_send_r2, 50000);
595 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_check_i2, 20000);604 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_check_i2, 20000);
596 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_handle_i2, 30000);605 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_handle_i2, 30000);
606 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_update_retransmissions, 30250);
597 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_setup_ipsec_sa, 30500);607 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_setup_ipsec_sa, 30500);
598 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_create_r2, 40000);608 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_create_r2, 40000);
599 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_add_rvs_reg_from, 41000);609 hip_register_handle_function(HIP_I2, HIP_STATE_I1_SENT, &hip_add_rvs_reg_from, 41000);
@@ -603,6 +613,7 @@
603 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_check_i2, 20000);613 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_check_i2, 20000);
604 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_handle_i2_in_i2_sent, 21000);614 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_handle_i2_in_i2_sent, 21000);
605 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_handle_i2, 30000);615 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_handle_i2, 30000);
616 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_update_retransmissions, 30250);
606 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_setup_ipsec_sa, 30500);617 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_setup_ipsec_sa, 30500);
607 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_create_r2, 40000);618 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_create_r2, 40000);
608 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_add_rvs_reg_from, 41000);619 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_add_rvs_reg_from, 41000);
@@ -611,6 +622,7 @@
611 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_send_r2, 50000);622 hip_register_handle_function(HIP_I2, HIP_STATE_I2_SENT, &hip_send_r2, 50000);
612 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_check_i2, 20000);623 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_check_i2, 20000);
613 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_handle_i2, 30000);624 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_handle_i2, 30000);
625 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_update_retransmissions, 30250);
614 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_setup_ipsec_sa, 30500);626 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_setup_ipsec_sa, 30500);
615 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_create_r2, 40000);627 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_create_r2, 40000);
616 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_add_rvs_reg_from, 41000);628 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_add_rvs_reg_from, 41000);
@@ -619,6 +631,7 @@
619 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_send_r2, 50000);631 hip_register_handle_function(HIP_I2, HIP_STATE_R2_SENT, &hip_send_r2, 50000);
620 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_check_i2, 20000);632 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_check_i2, 20000);
621 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_handle_i2, 30000);633 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_handle_i2, 30000);
634 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_update_retransmissions, 30250);
622 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_setup_ipsec_sa, 30500);635 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_setup_ipsec_sa, 30500);
623 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_create_r2, 40000);636 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_create_r2, 40000);
624 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_add_rvs_reg_from, 41000);637 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_add_rvs_reg_from, 41000);
@@ -627,6 +640,7 @@
627 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_send_r2, 50000);640 hip_register_handle_function(HIP_I2, HIP_STATE_ESTABLISHED, &hip_send_r2, 50000);
628 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_check_i2, 20000);641 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_check_i2, 20000);
629 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_handle_i2, 30000);642 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_handle_i2, 30000);
643 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_update_retransmissions, 30250);
630 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_setup_ipsec_sa, 30500);644 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_setup_ipsec_sa, 30500);
631 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_create_r2, 40000);645 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_create_r2, 40000);
632 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_add_rvs_reg_from, 41000);646 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_add_rvs_reg_from, 41000);
@@ -635,6 +649,7 @@
635 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_send_r2, 50000);649 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSING, &hip_send_r2, 50000);
636 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_check_i2, 20000);650 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_check_i2, 20000);
637 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_handle_i2, 30000);651 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_handle_i2, 30000);
652 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_update_retransmissions, 30250);
638 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_setup_ipsec_sa, 30500);653 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_setup_ipsec_sa, 30500);
639 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_create_r2, 40000);654 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_create_r2, 40000);
640 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_add_rvs_reg_from, 41000);655 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_add_rvs_reg_from, 41000);
@@ -643,6 +658,7 @@
643 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_send_r2, 50000);658 hip_register_handle_function(HIP_I2, HIP_STATE_CLOSED, &hip_send_r2, 50000);
644 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_check_i2, 20000);659 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_check_i2, 20000);
645 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_handle_i2, 30000);660 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_handle_i2, 30000);
661 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_update_retransmissions, 30250);
646 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_setup_ipsec_sa, 30500);662 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_setup_ipsec_sa, 30500);
647 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_create_r2, 40000);663 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_create_r2, 40000);
648 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_add_rvs_reg_from, 41000);664 hip_register_handle_function(HIP_I2, HIP_STATE_NONE, &hip_add_rvs_reg_from, 41000);
@@ -652,6 +668,7 @@
652668
653 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_check_r1, 20000);669 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_check_r1, 20000);
654 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_r1, 30000);670 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_r1, 30000);
671 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_update_retransmissions, 30500);
655 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_build_esp_info, 31000);672 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_build_esp_info, 31000);
656 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_build_solution, 32000);673 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_build_solution, 32000);
657 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_diffie_hellman, 33000);674 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_handle_diffie_hellman, 33000);
@@ -663,6 +680,7 @@
663 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_send_i2, 50000);680 hip_register_handle_function(HIP_R1, HIP_STATE_I1_SENT, &hip_send_i2, 50000);
664 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_check_r1, 20000);681 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_check_r1, 20000);
665 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_r1, 30000);682 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_r1, 30000);
683 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_update_retransmissions, 30500);
666 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_build_esp_info, 31000);684 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_build_esp_info, 31000);
667 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_build_solution, 32000);685 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_build_solution, 32000);
668 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_diffie_hellman, 33000);686 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_handle_diffie_hellman, 33000);
@@ -674,6 +692,7 @@
674 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_send_i2, 50000);692 hip_register_handle_function(HIP_R1, HIP_STATE_I2_SENT, &hip_send_i2, 50000);
675 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_check_r1, 20000);693 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_check_r1, 20000);
676 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_r1, 30000);694 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_r1, 30000);
695 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_update_retransmissions, 30500);
677 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_build_esp_info, 31000);696 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_build_esp_info, 31000);
678 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_build_solution, 32000);697 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_build_solution, 32000);
679 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_diffie_hellman, 33000);698 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_handle_diffie_hellman, 33000);
@@ -685,6 +704,7 @@
685 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_send_i2, 50000);704 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSING, &hip_send_i2, 50000);
686 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_check_r1, 20000);705 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_check_r1, 20000);
687 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_r1, 30000);706 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_r1, 30000);
707 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_update_retransmissions, 30500);
688 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_build_esp_info, 31000);708 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_build_esp_info, 31000);
689 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_build_solution, 32000);709 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_build_solution, 32000);
690 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_diffie_hellman, 33000);710 hip_register_handle_function(HIP_R1, HIP_STATE_CLOSED, &hip_handle_diffie_hellman, 33000);
@@ -697,6 +717,7 @@
697717
698 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_check_r2, 20000);718 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_check_r2, 20000);
699 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_handle_r2, 30000);719 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_handle_r2, 30000);
720 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_update_retransmissions, 30250);
700 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_setup_ipsec_sa, 30500);721 hip_register_handle_function(HIP_R2, HIP_STATE_I2_SENT, &hip_setup_ipsec_sa, 30500);
701722
702 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I1_SENT, &hip_check_notify, 20000);723 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_I1_SENT, &hip_check_notify, 20000);
@@ -712,18 +733,22 @@
712 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSED, &hip_check_notify, 20000);733 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSED, &hip_check_notify, 20000);
713 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSED, &hip_handle_notify, 30000);734 hip_register_handle_function(HIP_NOTIFY, HIP_STATE_CLOSED, &hip_handle_notify, 30000);
714735
715 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_check_packet, 20000);736 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_check_packet, 20000);
716 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_create_response, 30000);737 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_update_retransmissions, 25000);
717 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_send_response, 40000);738 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_create_response, 30000);
739 hip_register_handle_function(HIP_CLOSE, HIP_STATE_ESTABLISHED, &hip_close_send_response, 40000);
718740
719 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_check_packet, 20000);741 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_check_packet, 20000);
720 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_create_response, 30000);742 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_update_retransmissions, 25000);
721 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_send_response, 40000);743 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_create_response, 30000);
744 hip_register_handle_function(HIP_CLOSE, HIP_STATE_CLOSING, &hip_close_send_response, 40000);
722745
723 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_close_ack_check_packet, 20000);746 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_close_ack_check_packet, 20000);
747 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_update_retransmissions, 25000);
724 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_close_ack_handle_packet, 30000);748 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSING, &hip_close_ack_handle_packet, 30000);
725749
726 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_close_ack_check_packet, 20000);750 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_close_ack_check_packet, 20000);
751 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_update_retransmissions, 25000);
727 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_close_ack_handle_packet, 30000);752 hip_register_handle_function(HIP_CLOSE_ACK, HIP_STATE_CLOSED, &hip_close_ack_handle_packet, 30000);
728753
729 hip_register_handle_function(HIP_LUPDATE, HIP_STATE_ESTABLISHED, &esp_prot_handle_light_update, 20000);754 hip_register_handle_function(HIP_LUPDATE, HIP_STATE_ESTABLISHED, &esp_prot_handle_light_update, 20000);
730755
=== modified file 'hipd/input.c'
--- hipd/input.c 2011-12-09 09:32:56 +0000
+++ hipd/input.c 2011-12-29 15:06:25 +0000
@@ -58,6 +58,7 @@
58#include "lib/core/state.h"58#include "lib/core/state.h"
59#include "lib/core/transform.h"59#include "lib/core/transform.h"
60#include "lib/tool/xfrmapi.h"60#include "lib/tool/xfrmapi.h"
61#include "modules/update/hipd/update.h"
61#include "config.h"62#include "config.h"
62#include "cookie.h"63#include "cookie.h"
63#include "dh.h"64#include "dh.h"
@@ -1113,8 +1114,6 @@
1113 hip_perf_stop_benchmark(perf_set, PERF_BASE);1114 hip_perf_stop_benchmark(perf_set, PERF_BASE);
1114 hip_perf_write_benchmark(perf_set, PERF_BASE);1115 hip_perf_write_benchmark(perf_set, PERF_BASE);
1115#endif1116#endif
1116 ctx->hadb_entry->hip_msg_retrans.count = 0;
1117 memset(ctx->hadb_entry->hip_msg_retrans.buf, 0, HIP_MAX_NETWORK_PACKET);
11181117
1119 if (ctx->hadb_entry->state == HIP_STATE_ESTABLISHED) {1118 if (ctx->hadb_entry->state == HIP_STATE_ESTABLISHED) {
1120 HIP_DEBUG("Send response to firewall.\n");1119 HIP_DEBUG("Send response to firewall.\n");
@@ -1695,9 +1694,6 @@
1695 ctx->hadb_entry->state = HIP_STATE_ESTABLISHED;1694 ctx->hadb_entry->state = HIP_STATE_ESTABLISHED;
1696 HIP_INFO("Reached %s state\n", hip_state_str(ctx->hadb_entry->state));1695 HIP_INFO("Reached %s state\n", hip_state_str(ctx->hadb_entry->state));
16971696
1698 ctx->hadb_entry->hip_msg_retrans.count = 0;
1699 memset(ctx->hadb_entry->hip_msg_retrans.buf, 0, HIP_MAX_NETWORK_PACKET);
1700
1701out_err:1697out_err:
1702 if (err) {1698 if (err) {
1703 ctx->error = err;1699 ctx->error = err;
@@ -1877,3 +1873,121 @@
18771873
1878 return err;1874 return err;
1879}1875}
1876
1877/**
1878 * Clear the given retransmission.
1879 * i.e. set the remaining retransmissions to zero and zero the buffer.
1880 *
1881 * @param retrans The retransmission to be cleared.
1882 */
1883void hip_clear_retransmission(struct hip_msg_retrans *const retrans)
1884{
1885 if (!retrans) {
1886 return;
1887 }
1888
1889 retrans->count = 0;
1890 if (retrans->buf) {
1891 memset(retrans->buf, 0, hip_get_msg_total_len(retrans->buf));
1892 }
1893}
1894
1895/**
1896 * Decide whether the given UPDATE retransmission is still valid with regard to
1897 * the incoming message. For example a buffered U1 packet is invalidated when a
1898 * fresh U2 comes in.
1899 *
1900 * @param ctx The packet context of the incoming transmission.
1901 * @param retrans The retransmission in question.
1902 * @return True if given retransmission is invalid.
1903 * False else.
1904 */
1905static bool update_retrans_is_invalid(struct hip_packet_context *const ctx,
1906 struct hip_msg_retrans *const retrans)
1907{
1908 if (!ctx || !retrans) {
1909 return false;
1910 }
1911
1912 switch (hip_classify_update_type(ctx->input_msg)) {
1913 case SECOND_UPDATE_PACKET:
1914 return hip_classify_update_type(retrans->buf) == FIRST_UPDATE_PACKET;
1915
1916 case THIRD_UPDATE_PACKET:
1917 return hip_classify_update_type(retrans->buf) == SECOND_UPDATE_PACKET;
1918
1919 default:
1920 return false;
1921 }
1922}
1923
1924/**
1925 * Update our buffered retransmissions after receiving the given packet.
1926 * This functions removes invalid retransmissions after a state change caused
1927 * by a received packet. For example after successfully receiving and handling
1928 * an I2 or R2 packet all our buffered packets are dropped.
1929 *
1930 * Call this function after successful handling of the incoming packet.
1931 *
1932 * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
1933 * @param ha_state The host association state (RFC 5201, 4.4.1.)
1934 * @param ctx The packet context of the incoming transmission.
1935 *
1936 * @return Always 0. Nothing unforeseen may happen here which is important
1937 * enough to break the packet processing. Unhandled incoming message
1938 * types are simply ignored. Handle functions have to return an int
1939 * though so always 0 it is.
1940 */
1941int hip_update_retransmissions(UNUSED const uint8_t packet_type,
1942 UNUSED const enum hip_state ha_state,
1943 struct hip_packet_context *const ctx)
1944{
1945 struct hip_msg_retrans *retrans;
1946
1947 HIP_ASSERT(ctx);
1948 HIP_ASSERT(ctx->input_msg);
1949
1950 /* When receiving an I1 there usually is no established state yet. */
1951 if (!ctx->hadb_entry) {
1952 return 0;
1953 }
1954
1955 for (unsigned int i = 0; i < HIP_RETRANSMIT_QUEUE_SIZE; i++) {
1956 retrans = &ctx->hadb_entry->hip_msg_retrans[i];
1957
1958 if (retrans->count == 0) {
1959 continue;
1960 }
1961
1962 switch (hip_get_msg_type(ctx->input_msg)) {
1963 case HIP_I1:
1964 /* We only remove our sent I1s when we have got a greater HIT
1965 * than the peer (ref. RFC 5201, 4.4.2). */
1966 if (hip_get_msg_type(retrans->buf) == HIP_I1 &&
1967 hip_hit_is_bigger(&ctx->hadb_entry->hit_our, &ctx->hadb_entry->hit_peer)) {
1968 hip_clear_retransmission(retrans);
1969 }
1970 break;
1971
1972 case HIP_I2:
1973 case HIP_R1:
1974 case HIP_R2:
1975 case HIP_CLOSE:
1976 case HIP_CLOSE_ACK:
1977 hip_clear_retransmission(retrans);
1978 break;
1979
1980 case HIP_UPDATE:
1981 if (update_retrans_is_invalid(ctx, retrans)) {
1982 hip_clear_retransmission(retrans);
1983 }
1984 break;
1985
1986 /* We do not act on other message types like Light UPDATE for example. */
1987 default:
1988 break;
1989 }
1990 }
1991
1992 return 0;
1993}
18801994
=== modified file 'hipd/input.h'
--- hipd/input.h 2011-11-25 17:56:24 +0000
+++ hipd/input.h 2011-12-29 15:06:25 +0000
@@ -127,4 +127,10 @@
127 UNUSED const enum hip_state ha_state,127 UNUSED const enum hip_state ha_state,
128 struct hip_packet_context *ctx);128 struct hip_packet_context *ctx);
129129
130void hip_clear_retransmission(struct hip_msg_retrans *const retrans);
131
132int hip_update_retransmissions(UNUSED const uint8_t packet_type,
133 UNUSED const enum hip_state ha_state,
134 struct hip_packet_context *const ctx);
135
130#endif /* HIPL_HIPD_INPUT_H */136#endif /* HIPL_HIPD_INPUT_H */
131137
=== modified file 'hipd/maintenance.c'
--- hipd/maintenance.c 2011-12-21 10:54:26 +0000
+++ hipd/maintenance.c 2011-12-29 15:06:25 +0000
@@ -60,6 +60,7 @@
60#include "hidb.h"60#include "hidb.h"
61#include "hipd.h"61#include "hipd.h"
62#include "init.h"62#include "init.h"
63#include "input.h"
63#include "output.h"64#include "output.h"
64#include "maintenance.h"65#include "maintenance.h"
6566
@@ -89,55 +90,48 @@
89 * @param current_time current time90 * @param current_time current time
90 * @return zero on success or negative on failure91 * @return zero on success or negative on failure
91 */92 */
92static int handle_retransmission(struct hip_hadb_state *entry,93static int handle_retransmissions(struct hip_hadb_state *entry,
93 void *current_time)94 void *current_time)
94{95{
95 int err = 0;96 int err = 0, i = 0;
96 time_t *now = current_time;97 struct hip_msg_retrans *retrans;
9798 time_t *now = current_time;
98 if (entry->hip_msg_retrans.count == 0) {99
99 goto out_err;100 for (i = 0; i < HIP_RETRANSMIT_QUEUE_SIZE; i++) {
100 }101 retrans = &entry->hip_msg_retrans[(entry->next_retrans_slot + i) %
101102 HIP_RETRANSMIT_QUEUE_SIZE];
102 /* check if the last transmission was at least RETRANSMIT_WAIT seconds ago */103
103 if (*now - HIP_RETRANSMIT_WAIT > entry->hip_msg_retrans.last_transmit) {104 /* check if the last transmission was at least RETRANSMIT_WAIT seconds ago */
104 if (entry->hip_msg_retrans.count > 0 &&105 if (*now - HIP_RETRANSMIT_WAIT > retrans->last_transmit) {
105 ((entry->state != HIP_STATE_ESTABLISHED && entry->retrans_state != entry->state) ||106 if (retrans->count > 0) {
106 entry->light_update_retrans == 1)) {107 /* @todo: verify that this works over slow ADSL line */
107 HIP_DEBUG("state=%d, retrans_state=%d\n", entry->state, entry->retrans_state);108 if (hip_send_pkt(&retrans->saddr,
108109 &retrans->daddr,
109 /* @todo: verify that this works over slow ADSL line */110 entry->nat_mode ? hip_get_local_nat_udp_port() : 0,
110 err = hip_send_pkt(&entry->hip_msg_retrans.saddr,111 entry->peer_udp_port,
111 &entry->hip_msg_retrans.daddr,112 retrans->buf,
112 entry->nat_mode ? hip_get_local_nat_udp_port() : 0,113 entry, 0) == 0) {
113 entry->peer_udp_port,114 /* Set entry state, if previous state was unassociated
114 entry->hip_msg_retrans.buf,115 * and type is I1. */
115 entry, 0);116 if (hip_get_msg_type(retrans->buf) == HIP_I1 &&
116117 entry->state == HIP_STATE_UNASSOCIATED) {
117 /* Set entry state, if previous state was unassociated118 HIP_DEBUG("Resent I1 succcesfully\n");
118 * and type is I1. */119 entry->state = HIP_STATE_I1_SENT;
119 if (!err && hip_get_msg_type(entry->hip_msg_retrans.buf)120 }
120 == HIP_I1 && entry->state == HIP_STATE_UNASSOCIATED) {121 } else {
121 HIP_DEBUG("Resent I1 succcesfully\n");122 HIP_ERROR("Failed to retransmit packet of type %d.\n",
122 entry->state = HIP_STATE_I1_SENT;123 hip_get_msg_type(retrans->buf));
123 }124 err = -1;
124125 }
125 entry->hip_msg_retrans.count--;126
126 time(&entry->hip_msg_retrans.last_transmit);127 retrans->count--;
127 } else {128 time(&retrans->last_transmit);
128 entry->hip_msg_retrans.count = 0;129 } else if (hip_get_msg_type(retrans->buf)) {
129 memset(entry->hip_msg_retrans.buf, 0, HIP_MAX_NETWORK_PACKET);130 hip_clear_retransmission(retrans);
130
131 if (entry->state == HIP_STATE_ESTABLISHED) {
132 entry->retrans_state = HIP_STATE_NONE;
133 } else {
134 entry->retrans_state = entry->state;
135 }131 }
136 }132 }
137 }133 }
138134
139out_err:
140
141 return err;135 return err;
142}136}
143137
@@ -151,7 +145,7 @@
151 time_t current_time;145 time_t current_time;
152 time(&current_time);146 time(&current_time);
153147
154 if (hip_for_each_ha(handle_retransmission, &current_time)) {148 if (hip_for_each_ha(handle_retransmissions, &current_time)) {
155 return -1;149 return -1;
156 }150 }
157 return 0;151 return 0;
158152
=== modified file 'hipd/netdev.c'
--- hipd/netdev.c 2011-12-09 09:32:56 +0000
+++ hipd/netdev.c 2011-12-29 15:06:25 +0000
@@ -921,12 +921,15 @@
921921
922send_i1:922send_i1:
923923
924 if (entry->hip_msg_retrans.count == 0) {924 HIP_DEBUG("Checking for older queued I1 transmissions.\n");
925 HIP_DEBUG("Expired retransmissions, sending i1\n");925 for (unsigned int i = 0; i < HIP_RETRANSMIT_QUEUE_SIZE; i++) {
926 } else {926 if (entry->hip_msg_retrans[i].count > 0
927 HIP_DEBUG("I1 was already sent, ignoring\n");927 && hip_get_msg_type(entry->hip_msg_retrans[i].buf) == HIP_I1) {
928 goto out_err;928 HIP_DEBUG("I1 was already sent, ignoring\n");
929 goto out_err;
930 }
929 }931 }
932 HIP_DEBUG("Expired retransmissions, sending i1\n");
930933
931 is_ipv4_locator = IN6_IS_ADDR_V4MAPPED(&entry->peer_addr);934 is_ipv4_locator = IN6_IS_ADDR_V4MAPPED(&entry->peer_addr);
932935
933936
=== modified file 'hipd/output.c'
--- hipd/output.c 2011-11-10 10:53:21 +0000
+++ hipd/output.c 2011-12-29 15:06:25 +0000
@@ -1066,7 +1066,7 @@
1066 err = hip_send_pkt(&ctx->dst_addr, &ctx->src_addr,1066 err = hip_send_pkt(&ctx->dst_addr, &ctx->src_addr,
1067 ctx->hadb_entry->nat_mode ? hip_get_local_nat_udp_port() : 0,1067 ctx->hadb_entry->nat_mode ? hip_get_local_nat_udp_port() : 0,
1068 ctx->hadb_entry->peer_udp_port, ctx->output_msg,1068 ctx->hadb_entry->peer_udp_port, ctx->output_msg,
1069 ctx->hadb_entry, 1);1069 ctx->hadb_entry, 0);
10701070
1071 HIP_IFEL(err, -ECOMM, "Sending R2 packet failed.\n");1071 HIP_IFEL(err, -ECOMM, "Sending R2 packet failed.\n");
10721072
@@ -1111,29 +1111,30 @@
1111 * destination HITs.1111 * destination HITs.
1112 * @param entry a pointer to the current host association database state.1112 * @param entry a pointer to the current host association database state.
1113 * @return zero1113 * @return zero
1114 * @note currently the queue length is one and new packets replace old ones
1115 */1114 */
1116static int queue_packet(const struct in6_addr *src_addr,1115static int queue_packet(const struct in6_addr *src_addr,
1117 const struct in6_addr *peer_addr,1116 const struct in6_addr *peer_addr,
1118 const struct hip_common *msg,1117 const struct hip_common *msg,
1119 struct hip_hadb_state *entry)1118 struct hip_hadb_state *entry)
1120{1119{
1121 int len = hip_get_msg_total_len(msg);1120 struct hip_msg_retrans *retrans;
11221121
1123 if (!entry) {1122 if (!entry) {
1124 return 0;1123 return 0;
1125 }1124 }
11261125
1126 retrans = &entry->hip_msg_retrans[entry->next_retrans_slot];
1127
1127 /* Not reusing the old entry as the new packet may have different length */1128 /* Not reusing the old entry as the new packet may have different length */
1128 memset(entry->hip_msg_retrans.buf, 0, HIP_MAX_NETWORK_PACKET);1129 memset(retrans->buf, 0, HIP_MAX_NETWORK_PACKET);
11291130
1130 memcpy(entry->hip_msg_retrans.buf, msg, len);1131 memcpy(retrans->buf, msg, hip_get_msg_total_len(msg));
1131 memcpy(&entry->hip_msg_retrans.saddr, src_addr,1132 ipv6_addr_copy(&retrans->saddr, src_addr);
1132 sizeof(struct in6_addr));1133 ipv6_addr_copy(&retrans->daddr, peer_addr);
1133 memcpy(&entry->hip_msg_retrans.daddr, peer_addr,1134 retrans->count = HIP_RETRANSMIT_MAX;
1134 sizeof(struct in6_addr));1135 time(&retrans->last_transmit);
1135 entry->hip_msg_retrans.count = HIP_RETRANSMIT_MAX;1136
1136 time(&entry->hip_msg_retrans.last_transmit);1137 entry->next_retrans_slot = (entry->next_retrans_slot + 1) % HIP_RETRANSMIT_QUEUE_SIZE;
11371138
1138 return 0;1139 return 0;
1139}1140}
11401141
=== modified file 'lib/core/state.h'
--- lib/core/state.h 2011-12-16 13:37:33 +0000
+++ lib/core/state.h 2011-12-29 15:06:25 +0000
@@ -100,6 +100,9 @@
100 HIP_HA_STATE_VALID = 1,100 HIP_HA_STATE_VALID = 1,
101};101};
102102
103/* The maximum number of retransmissions to queue. */
104#define HIP_RETRANSMIT_QUEUE_SIZE 3
105
103/**106/**
104 * A data structure for handling retransmission. Used inside host association107 * A data structure for handling retransmission. Used inside host association
105 * database entries.108 * database entries.
@@ -157,9 +160,6 @@
157 int purge_timeout;160 int purge_timeout;
158 /** The state of this host association. */161 /** The state of this host association. */
159 enum hip_state state;162 enum hip_state state;
160 /** This guarantees that retransmissions work properly also in
161 * non-established state.*/
162 enum hip_state retrans_state;
163 /** Our control values related to this host association.163 /** Our control values related to this host association.
164 * @see hip_ha_controls */164 * @see hip_ha_controls */
165 hip_controls local_controls;165 hip_controls local_controls;
@@ -282,8 +282,11 @@
282 unsigned char echo_data[4];282 unsigned char echo_data[4];
283283
284 HIP_HASHTABLE *peer_addr_list_to_be_added;284 HIP_HASHTABLE *peer_addr_list_to_be_added;
285 /** The slot in our struct hip_msg_retrans array which will be used to save
286 * the next retransmission. */
287 unsigned int next_retrans_slot;
285 /** For storing retransmission related data. */288 /** For storing retransmission related data. */
286 struct hip_msg_retrans hip_msg_retrans;289 struct hip_msg_retrans hip_msg_retrans[HIP_RETRANSMIT_QUEUE_SIZE];
287 /** peer hostname */290 /** peer hostname */
288 uint8_t peer_hostname[HIP_HOST_ID_HOSTNAME_LEN_MAX];291 uint8_t peer_hostname[HIP_HOST_ID_HOSTNAME_LEN_MAX];
289 /** Counters of heartbeats (ICMPv6s) */292 /** Counters of heartbeats (ICMPv6s) */
290293
=== modified file 'modules/update/hipd/update.c'
--- modules/update/hipd/update.c 2011-12-16 13:37:33 +0000
+++ modules/update/hipd/update.c 2011-12-29 15:06:25 +0000
@@ -364,7 +364,7 @@
364 ctx->hadb_entry->peer_udp_port,364 ctx->hadb_entry->peer_udp_port,
365 ctx->output_msg,365 ctx->output_msg,
366 ctx->hadb_entry,366 ctx->hadb_entry,
367 1);367 0);
368 }368 }
369369
370 return err;370 return err;
@@ -810,6 +810,11 @@
810 -1, "Error on registering UPDATE handle function.\n");810 -1, "Error on registering UPDATE handle function.\n");
811 HIP_IFEL(hip_register_handle_function(HIP_UPDATE,811 HIP_IFEL(hip_register_handle_function(HIP_UPDATE,
812 HIP_STATE_R2_SENT,812 HIP_STATE_R2_SENT,
813 &hip_update_retransmissions,
814 20150),
815 -1, "Error on registering UPDATE handle function.\n");
816 HIP_IFEL(hip_register_handle_function(HIP_UPDATE,
817 HIP_STATE_R2_SENT,
813 &prepare_update_response,818 &prepare_update_response,
814 20200),819 20200),
815 -1, "Error on registering UPDATE handle function.\n");820 -1, "Error on registering UPDATE handle function.\n");
@@ -896,6 +901,11 @@
896 -1, "Error on registering UPDATE handle function.\n");901 -1, "Error on registering UPDATE handle function.\n");
897 HIP_IFEL(hip_register_handle_function(HIP_UPDATE,902 HIP_IFEL(hip_register_handle_function(HIP_UPDATE,
898 HIP_STATE_ESTABLISHED,903 HIP_STATE_ESTABLISHED,
904 &hip_update_retransmissions,
905 20150),
906 -1, "Error on registering UPDATE handle function.\n");
907 HIP_IFEL(hip_register_handle_function(HIP_UPDATE,
908 HIP_STATE_ESTABLISHED,
899 &prepare_update_response,909 &prepare_update_response,
900 20200),910 20200),
901 -1, "Error on registering UPDATE handle function.\n");911 -1, "Error on registering UPDATE handle function.\n");

Subscribers

People subscribed via source and target branches

to all changes: