Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [cf-dev] cf-dev Digest, Vol 9, Issue 6

Cf keeps all communication state in the Exchange objects. This state is used for both, matching messages and deduplication. Completed exchanges are kept until the MID lifetime expires, so the original reply can be sent when a duplicate arrives. This makes the logic a bit more complicated, but reduces the lookups to get all the required information.


Reading again at your first message, I understand that you propose to add the "origin" in the KeyMID and continue to put the exchange found in exchangesByToken in the deduplicator to deduplicate ACKs (that would be then correctly filtered by the origin) ?

The origin is already in the KeyMID through the address, but by mistake the remote address is set even when the MID originates locally.

But in our case, with no other change,  the keyMID would always contain the same source (the server address), same mid (because of client/server collision), potentially the same token (nothing prevents to use the same token for successive requests, am I wrong ?) and even the same LOCAL origin (since all request were initially sent from the Cf client) ? In my opinion, in order to work, every sent request would then also have to be added to the deduplicator, for instance with the local address.

The first 0x4711 from the figure originates at the server (CON separate response). So the KeyMID would contain the server endpoint-address. The second, conflicting 0x4711 originates at the client (CON request), so the KeyMID should contain the local address.

During the lookup, we then have to use the correct KeyMID based on the direction of the messages: incoming ACKs/RSTs need to look for the local (=destination) address, incoming CONs/NONs for the remote (=source) address. This way, your described situation should not cause a conflict.


Our idea was to use deduplication only for exchanges from remote origin, and then forget deduplication for ACKs (a non-matching ACK will simply be ignored). I did not find requirements in the specification to process ACK duplicates. Do you have a pointer on the subject ?

If you only implement the server role, this works. Besides the exchanges from remote origin of which you take care, it will only receive empty ACKs and RSTs (which are always empty). Either you find the open transmission to stop or you do not, and hence simply ignore it. I cannot see any other negative effect here. (Callbacks to the application upon empty ACKs should be avoided anyway, because they do not exist on some alternative transports---I heard that some people did that for CON notifications...)

For the client role, you must avoid calling the response callback twice (when only implementing the protocol stack, you never know what the application logic will do). This should be done by using proper token management (randomized tokens are recommended). Think of this scenario:

Client                  Server

  |                       |

  |---CON, Token: empty-->|

  |<---ACK----------------|

  |                       |

Separate Response

  |                       |

  |<---CON, Token: empty--|-_

  |---ACK--->X            |  \

  |                       |   |

New request                   |

  |                       |   | Retransmission

  |---CON, Token: empty-->|   |

  |                       |  /

  |<---CON, Token: empty--|-´

Looks like implicit acknowledgement...

 


About the other point, which was another subject in fact, what I was trying to tell, is that as generated mids are managed globally (variable currendMID), segmenting exchanges by destination in exchangesByMid was not really necessary. The namespace for generated mids is in fact the local endpoint (except if I made a mistake and if the map contains all exchanges, even "remote" ones), so that does not break your rule ? But it was an embedded C remark, focusing on optimization. This can allow detecting bad peer implementations.

Yes, Cf keeps a single MID counter per local CoapEndpoint for all remotes. Setting the destination address for locally originating MIDs is the bug here! However, we still need the address field to distinguish local MIDs from remote MIDs (e.g., separate responses and notifications) to avoid the scenario you described.

Don't bother if I'm all wrong, you surely better know CoAP than I do and will find the best fix for Cf.

I hope that helped! I think I got some good input for the lwig-coap draft! :)

Ciao
Matthias


Back to the top