Re: [Dots] [core] WG Last Call on draft-ietf-core-new-block

supjps-ietf@jpshallow.com Fri, 08 January 2021 17:17 UTC

Return-Path: <jon.shallow@jpshallow.com>
X-Original-To: dots@ietfa.amsl.com
Delivered-To: dots@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 218B03A1167 for <dots@ietfa.amsl.com>; Fri, 8 Jan 2021 09:17:21 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.899
X-Spam-Level:
X-Spam-Status: No, score=-1.899 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=unavailable autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7vfbl2xa2lKo for <dots@ietfa.amsl.com>; Fri, 8 Jan 2021 09:17:16 -0800 (PST)
Received: from mail.jpshallow.com (mail.jpshallow.com [217.40.240.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 2F30C3A116F for <dots@ietf.org>; Fri, 8 Jan 2021 09:17:16 -0800 (PST)
Received: from mail2.jpshallow.com ([192.168.0.3] helo=N01332) by mail.jpshallow.com with esmtp (Exim 4.92.3) (envelope-from <jon.shallow@jpshallow.com>) id 1kxvNu-0003r5-Mp; Fri, 08 Jan 2021 17:17:10 +0000
From: <supjps-ietf@jpshallow.com>
To: "Marco Tiloca" <marco.tiloca@ri.se>, <christian@amsuess.com>, <draft-ietf-core-new-block@ietf.org>
Cc: <dots@ietf.org>, <core@ietf.org>
References: <022401d6e440$06763ba0$1362b2e0$@jpshallow.com> <fa7956ae-31a3-7724-3af4-4e755a719045@ri.se> <041101d6e5c2$e17fbef0$a47f3cd0$@jpshallow.com> <a549b34f-3f72-a6df-b2c3-ae9d3759b701@ri.se>
In-Reply-To: <a549b34f-3f72-a6df-b2c3-ae9d3759b701@ri.se>
Date: Fri, 8 Jan 2021 17:17:23 -0000
Message-ID: <047b01d6e5e2$2115ba50$63412ef0$@jpshallow.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Mailer: Microsoft Outlook 14.0
Thread-Index: AQKHUmmxquhArXd4h/ZvumPsHfcPaAFUavWxAaeeZ2wB9CJyVaiVik3w
Content-Language: en-gb
Archived-At: <https://mailarchive.ietf.org/arch/msg/dots/MvVV-fAtzRwyroOePUV3WcmjYl8>
Subject: Re: [Dots] [core] WG Last Call on draft-ietf-core-new-block
X-BeenThere: dots@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "List for discussion of DDoS Open Threat Signaling \(DOTS\) technology and directions." <dots.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/dots>, <mailto:dots-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/dots/>
List-Post: <mailto:dots@ietf.org>
List-Help: <mailto:dots-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/dots>, <mailto:dots-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 08 Jan 2021 17:17:21 -0000

Hi Marco,

Thanks for this.

The new updates have been pushed to https://github.com/core-wg/new-block and the differences with the draft can be found at https://www.ietf.org/rfcdiff?url1=draft-ietf-core-new-block&url2=https://raw.githubusercontent.com/core-wg/new-block/master/draft-ietf-core-new-block.txt

The PR for the responses below can be found at https://github.com/core-wg/new-block/pull/11 

Otherwise see inline.

Regards

Jon

> -----Original Message-----
> From: Marco Tiloca [mailto: marco.tiloca@ri.se]
> Sent: 08 January 2021 15:57
> To: supjps-ietf@jpshallow.com; christian@amsuess.com; draft-ietf-core-new-
> block@ietf.org
> Cc: dots@ietf.org; core@ietf.org
> Subject: Re: [core] WG Last Call on draft-ietf-core-new-block
> 
> Hi Jon,
> 
> Thanks, the changes look good. Just a few minor things.
> 
> 
> * In Section 3.4, about the second case:
> 
>   - s/can continue to sent/can continue to send

[Jon] Fixed
> 
>   - It should be as explicit as in Section 6.2, i.e. "... 'NUM modulo
> MAX_PAYLOADS' is zero, while NUM is not zero: ..."

[Jon] Updated to be more explicit.
> 
>   - The word "current" can be misleading, if its relation with the value of
> NUM in the Q-Block2 option is not clarified. Based on the new example in
> Figure 8, I think you mean the latest set completely transferred to the
> client, whose last block has block number (NUM - 1). A possible overall
> rephrasing can be:
> 
>   "This is used to confirm that the current set of MAX_PAYLOADS payloads
> (the latest one having block number NUM-1) has been successfully received
> and that, upon receipt of this request, the server can continue to send the
> next set of payloads (the first one having block number NUM). This is the
> 'Continue' Q-Block-2."

[Jon] Thanks - gone with your suggestion
> 
> 
> * In Section 3.4, about the third case: I guess you mean: "This is a request for
> that block and for all of the remaining blocks in the current MAX_PAYLOADS
> set."
[Jon] Yes, updated.
> 
> 
> * Section 4 says: "The token to use ... any troubleshooting."
> 
>    Do you actually mean the highest block number received so far under that
> Request-Tag, or the highest within the current set of MAX_PAYLOADS
> payloads for which the server is requesting some missing blocks?
> 
>    The new example in Section 5 seems to cover the latter, which I guess is
> what you intend.

[Jon] Not sure that it really makes any difference.  Have updated the text to try to clarify
OLD
The token to use for the response SHOULD be the token that was used in the highest block number received payload. Note that the use of any received token would work, but providing the one used in the highest received block number will aid any troubleshooting. The client will use the token to match the request to find what Request-Tag value is currently being used.
NEW
The token to use for the response SHOULD be the token that was used in the highest block number received so far with the same Request-Tag value. Note that the use of any received token with the same Request-Tag would work, but providing the one used in the highest received block number will aid any troubleshooting. The client will use the token to determine what is the previously sent request to obtain the Request-Tag value to be used.
> 
> 
> * In Section 9.2:
> 
>   - Figure 7, the request should have the M bit set, i.e. QB2:0/1/1024
[Jon] Fixed - you spotted this before and I broke it again with a cut 'n paste.
> 
>   - Figure 8, the last response should have block number 10, i.e.
> QB2:10/0/1024
[Jon] Fixed
> 
>   - Figure 10, all responses should have ET=24

[Jon] Fixed (I only found one)
~Jon
> 
> 
> Best,
> /Marco
> 
> 
> On 2021-01-08 14:33, supjps-ietf@jpshallow.com wrote:
> > Hi Marco,
> >
> > Thanks for this - and it is good to have another set of eyes checking things
> through.
> >
> > Updates have been pushed to
> >
> https://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Fcore-wg%2Fnew-
> block&amp;data=04%7C01%7Cmarco.tiloca%40ri.se%7
> >
> C2385ef89ef574a7c81f608d8b3da00ba%7C5a9809cf0bcb413a838a09ecc40cc9e
> 8%7
> >
> C0%7C0%7C637457096666452069%7CUnknown%7CTWFpbGZsb3d8eyJWIjoi
> MC4wLjAwMD
> >
> AiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&amp;sdata=
> LN79
> >
> Z8Ar4AICnpWDOFgkFi3g0Mwf72KPC0ewPW%2FZk3A%3D&amp;reserved=0
> and the
> > differences with the draft can be found at
> >
> https://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fww
> w.
> > ietf.org%2Frfcdiff%3Furl1%3Ddraft-ietf-core-new-
> block%26url2%3Dhttps%3
> > A%2F%2Fraw.githubusercontent.com%2Fcore-wg%2Fnew-
> block%2Fmaster%2Fdraf
> > t-ietf-core-new-
> block.txt&amp;data=04%7C01%7Cmarco.tiloca%40ri.se%7C23
> >
> 85ef89ef574a7c81f608d8b3da00ba%7C5a9809cf0bcb413a838a09ecc40cc9e8%
> 7C0%
> >
> 7C0%7C637457096666452069%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4
> wLjAwMDAiL
> >
> CJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&amp;sdata=gIc
> 2vkC
> > 1XGtyGb17WSmby%2FO9wzA2bMaxDUsl3jmOAL4%3D&amp;reserved=0
> >
> > Otherwise, please see inline.
> >
> > Regards
> >
> > Jon
> >
> >> -----Original Message-----
> >> From: Marco Tiloca [mailto: marco.tiloca@ri.se]
> >> Sent: 07 January 2021 12:17
> >> To: supjps-ietf@jpshallow.com; christian@amsuess.com;
> >> draft-ietf-core-new- block@ietf.org
> >> Cc: dots@ietf.org; core@ietf.org
> >> Subject: Re: [core] WG Last Call on draft-ietf-core-new-block
> >>
> >> Hi,
> >>
> >> Thanks for this revision and for addressing my comments already in
> >> version  -03.
> >>
> >> Please, see below some more comments on this version -04.
> >>
> >> Best,
> >> /Marco
> >>
> >>
> >> * s/There are one or more missing CBOR encoded missing block
> >> numbers./There are one or more CBOR encoded missing block numbers.
> > [Jon] Fixed.
> >>
> >> *  Section 4 now includes the new paragraph: "The token to use for
> >> the response SHOULD be the token that was used in the highest block
> >> number received payload.  The Q-Block1 Option from the same packet
> >> SHOULD be included."
> > [Jon] The Q-Block1 option actually is not needed as it can be derived by
> the client from the remembered token (which is used to derive the
> Request-Tag.
> > OLD
> > The Q-Block1 Option from the same packet SHOULD be included.
> > NEW
> > The client will use the token to match the request to find what
> > Request-Tag value is currently being used.  Providing the highest
> > received block number will aid any troubleshooting.
> >
> >>    Consistently, the example in Figure 5 should also have
> >> QB1:3/0/1024 in the
> >> 4.08 response with Token T:0xe3, and QB1:1/1/1024 in the 4.08
> >> response with Token T:0xe4.
> > [Jon] No change now needed.
> >>    Since "SHOULD" is used, when is it still fine or expected to not
> >> include Q-
> >> Block1 in a 4.08 response?
> > [Jon] Q-Block1 is no longer needed.
> >>
> >> * When commenting the example in Figure 5, Section 9.1 reads: "The
> >> Token just needs to be one of those that have been received for this
> >> Request-Tag, so the client can derive the Request-Tag."
> >>
> >>    Should this not be aligned with the SHOULD used in Section 4 about
> >> using the Token from the same packet conveying the highest block
> number?
> > [Jon] Agreed
> >>    You explained in your mail that the client keeps tracking all
> >> Tokens in the burst anyway, so maybe it's better to rather align the
> >> text in Section 4 with what suggested here in Section 9.1, i.e.
> >> responding with any of those Token values is just fine.
> > [Jon] I think that it is useful for the client to have a hint about
> > what is the latest block number received even if it does not make use
> > it - it may help in debugging from packet captures etc. which is why I
> added in the SHOULD in section 4.  So, I would prefer to align this with
> section 4 OLD The Token just needs to be one of those that have been
> received for this
> >    Request-Tag, so the client can derive the Request-Tag.
> > NEW
> > The token used in the response should be the token that was used in the
> highest block number received payload. The client can then derive the
> Request-Tag by matching the token with the sent request..
> >
> >>    In such a case, the Q-Block1 option included in the 4.08 response
> >> has still to be the one from the request conveying the highest block
> number.
> >> Correct?
> > [Jon] We are now dropping the need for Q-Block1 in the response.
> >>
> >> * The new text in Section 6.2 says: "... and the situation
> >> re-evaluated for another 24 hour period until there is no report of
> >> missing payloads under normal operating conditions."
> >>
> >>    When that happens, I suppose MAX_PAYLOADS is right away restored
> >> to the intended value, i.e. it is not incremented by 1 to start
> >> another 24-hour period evaluation. Correct?
> > [Jon] Updated for clarification
> > OLD
> >         report of missing payloads under normal operating conditions. Note
> >         that the CoAP peer will not know about the MAX_PAYLOADS change
> > until NEW
> >         report of missing payloads under normal operating conditions. The
> newly
> >         derived value for MAX_PAYLOADS should be used for both ends of this
> >        particular CoAP peer link. Note
> >         that the CoAP peer will not know about the MAX_PAYLOADS change
> > until
> >>
> >> * Section 6.2 says: "The request that the client sends to acknowledge
> >> the receipt of all the current set of MAX_PAYLOADS payloads SHOULD
> >> contain a special case Q-Block2 Option with NUM set to the first
> >> block of the next set of MAX_PAYLOADS payloads and the M bit set to 1."
> >>
> >>   Is it possible to reflect this in the example of Figure 6? It would
> >> require the body to have more than MAX_PAYLOADS blocks thus
> resulting
> >> in more bursts, which would be inherited by the examples in Figure 7 and
> Figure 8.
> > [Jon] Examples updated to include this information
> >>
> >> * In Section 9, it would be good to have the parameters defined in
> >> Section
> >> 6.2 and their values reflected in the examples, when applicable.
> >> E.g., MAX_PAYLOADS is at least 4 in these examples; the asked
> >> retransmissions are presumably due sometimes to MAX_PAYLOADS
> compared
> >> against the value of the latest received Q-Block1/Q-Block2, while
> >> sometimes to NON_RECEIVE_TIMEOUT.
> > [Jon] Examples updated to include this information
> >>
> >> * In the example in Figure 6, shouldn't the first request from the
> >> client have the M bit set to 1 in the Q-Block2 option, i.e. as
> >> QB2:0/1/1024 ? As per Section 3.4, that would indicate that the
> >> request is in fact for the block 0 and for all of the remaining blocks within
> the body.
> >
> > [Jon] Good catch - corrected.
> >
> > ~Jon
> >> On 2021-01-06 16:24, supjps-ietf@jpshallow.com wrote:
> >>> Hi Christian,
> >>>
> >>> Once again, thank you for the comprehensive review.
> >>>
> >>> Responses part 2.  A new version (-04) of the draft has been
> >>> published and can be found at
> >>>
> >>
> https://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdat
> >> a
> >>> tracker.ietf.org%2Fdoc%2Fdraft-ietf-core-new-
> >> block%2F&amp;data=04%7C01
> >>
> %7Cmarco.tiloca%40ri.se%7C52440c4d23e244168b2108d8b2574780%7C5a980
> >> 9cf0
> >>
> bcb413a838a09ecc40cc9e8%7C0%7C0%7C637455435959417764%7CUnknown
> >> %7CTWFpb
> >>
> GZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI
> >> 6Mn0
> >>
> %3D%7C2000&amp;sdata=MlMoSqfzcxDvyO41nqA2GfZ7QqYFfeaHvN8fwH7j
> >> gTY%3D&am
> >>> p;reserved=0
> >>>
> >>>
> >>> Part 1 responses were covered in the main by version -03, so you may
> >>> want to look at the -02 to -04 differences.
> >>>
> >>> The Congestion Control section has been re-written to simplify how
> >>> things work and has a new set of definitions. There is a separation
> >>> of Confirmable and Non-Confirmable Congestion Control with the
> >>> stated assumption that all of a body is sent as Non-Confirmable or
> Confirmable.
> >>>
> >>> Otherwise, see inline.
> >>>
> >>> Regards
> >>>
> >>> Jon
> >>>
> >>>> * The list of pros and cons (with the cons being almost trivial) does
> >>>>   not explain to the reader why these are not a replacement; I suggest
> >>>>   to add:
> >>> [Jon] Another disadvantage addition
> >>> NEW
> >>> To reduce the transmission times for CON transmission of large
> >>> bodies, NSTART needs to be increased from 1, but this affects
> >>> congestion control where other parameters need to be tuned  (Section
> >>> 4.7 of [RFC7252]).  Such tuning is out of scope of this document.
> >>>
> >>>> * "If the client transmits a new body of data with a new Request-Tag
> >>>>   to": Processing parallel requests is something Request-Tag opens up. I
> >>>>   don't see why there's a MUST to that; the server certainly MAY drop
> >>>>   the old request, but it may just as well process them in parallel.
> >>> [Jon] The intent here was that garbage collection would take place
> >>> sooner than later - especially when running in a lossy environment
> >>> and the client has updated information to transmit. I agree that
> >>> Request-Tag enables the possibility of sending multiple block
> >>> requests with different payloads, and so there is a possibility that
> >>> the client starts sending body A, then decides to send body B and
> >>> terminate A, but a packet from B arrives before a packet from body A
> >>> is received and so
> >> things fail as A does not complete.
> >>> OLD
> >>>    If the client transmits a new body of data with a new Request-Tag to
> >>>    the same resource on a server, the server MUST remove any partially
> >>>    received body held for a previous Request-Tag for that resource.
> >>> NEW
> >>>   If a server receives payloads with different Request-Tags for the
> >>> same resource, it should continue to process all the bodies as it
> >>> has no way of determining which is the latest version, or which
> >>> body, if any, the client is terminating the transmission for.
> >>>
> >>>   If the client elects to stop the transmission of a complete body, it
> >>>   SHOULD "forget" all tracked tokens associated with the body's
> >>> Request-Tag so that a reset message is generated for the invalid
> >>> token in the 4.08 (Request Entity Incomplete) response.  The server
> >>> on receipt of the reset message SHOULD delete the partial body.
> >>> END
> >>>
> >>>> * "If the server receives a duplicate block with the same Request-Tag":
> >>>>   Why? Being silent is the default on nonterminal blocks alredy, but in
> >>>>   a situation like figure 5 if the 2.04 is lost, that rule would make
> >>>>   it impossible for the client to ever get a successful response.
> >>>>
> >>>>   A better rule here may be to say that it processes it all the same
> >>>>   (and if the payload is distinct from the first transmission's payload,
> >>>>   it should err out.)
> >>> [Jon] Fair point
> >>> OLD
> >>>    If the server receives a duplicate block with the same Request-Tag,
> >>>    it SHOULD silently ignore the packet.
> >>> NEW
> >>>    If the server receives a duplicate block with the same Request-Tag,
> >>>    it SHOULD  ignore the payload of the packet, but MUST still
> >>> respond as if the block was received for the first time.
> >>>> * "If the server receives multiple requests (implied or otherwise) for
> >>>>   the same block, it MUST only send back one instance of that block.":
> >>>>   This might be read as "ever" rather than "per incoming request",
> where
> >>>>   probably the latter is meant.
> >>> [Jon] This text has already been updated following another review
> >>> "OLD If the server receives multiple requests
> >>>    (implied or otherwise) for the same block, it MUST only send back one
> >>>    instance of that block.
> >>> NEW
> >>> If the request includes multiple Q-Block2
> >>>    Options and these options overlap (e.g., combination of M being set
> >>>    (this and all the later blocks) and being unset (this individual
> >>>    block)) resulting in an individual block being requested multiple
> >>>    times, the server MUST only send back one instance of that block.
> >>>    This behavior is meant to prevent amplification attacks."
> >>>
> >>>> * "The ETag Option MUST NOT be used": This is more a factural than a
> >>>>   normative statement; it *can* not be used there as the server would
> >>>>   respond thusly. It may be used, but then that indicates that the
> >>>>   client is trying to verify a freshness. (However, the client should
> >>>>   not *start* sending an ETag once it learned the current resource's
> >>>>   ETag when still attempting to pull out more blocks, but that's also not
> >>>>   a normative requirement but a consequence of those two requests
> not
> >>>>   being matchable any more.)
> >>> [Jon] OK
> >>> OLD
> >>>    The ETag Option MUST NOT be used in the request as the server could
> >>>    respond with a 2.03 (Valid Response) with no payload.  If the server
> >>>    responds with a different ETag Option value (as the resource
> >>>    representation has changed), then the client SHOULD drop all the
> >>>    payloads for the current body that are no longer valid.
> >>> NEW
> >>>    The ETag Option should not be used in the request for missing
> >>> blocks as the server could respond with a 2.03 (Valid Response) with
> >>> no payload. It can be used in the request if the client wants to
> >>> check the freshness of the currently cached body response.
> >>>
> >>> If the server detects part way through a body transfer that the
> >>> resource data has changed and the server is not maintaining a cached
> >>> copy of the old data, then the body response SHOULD be restarted
> >>> with a different ETag Option value. Any subsequent missing block
> >>> requests MUST respond using the latest ETag Option value.
> >>>
> >>>  If the server responds during a body update with a different ETag
> >>> Option value (as the resource representation has changed), then the
> >>> client should treat the partial body with the old ETag as no longer
> >>> being
> >> fresh.
> >>> END
> >>>> * "then the client SHOULD drop all the payloads for the current body":
> >>>>   "Drop" is overly prescriptive; the client may well keep them, but
> >>>>   just can't consider them fresh any more. (If the client has ample
> >>>>   caching abilities, they might come in handy if the resource goes back
> >>>>   to that ETag state). Same for later "the client MUST remove any
> >>>>   partially received".
> >>> [Jon] See previous response, otherwise OLD
> >>>    If the server transmits a new body of data (e.g., a triggered
> >>>    Observe) with a new ETag to the same client as an additional
> >>>    response, the client MUST remove any partially received body held for
> >>>    a previous ETag.
> >>> NEW
> >>>    If the server transmits a new body of data (e.g., a triggered
> >>>    Observe) with a new ETag to the same client as an additional
> >>>    response, the client should remove any partially received body held
> for
> >>>    a previous ETag for that resource as it is unlikely the missing
> >>> blocks can be retrieved.
> >>>> * "For Confirmable transmission, the client SHOULD continue to": As
> >>>>   above in the other direction, that's not news.
> >>> [Jon] Again, we are not looking for a response (well, a request in
> >>> this case as needed by Block2), just an ACK OLD
> >>>    For Confirmable transmission, the client SHOULD continue to
> >>>    acknowledge each packet as well as issuing a separate GET, POST, PUT,
> >>>    FETCH, PATCH, or iPATCH for the missing blocks.
> >>> NEW
> >>>    For Confirmable transmission, the server continues to acknowledge
> >>>   each packet, but a response is not required (whether separate or
> >>>   piggybacked) until successful receipt of the body or, if some of the
> >>>   payloads are sent as Non-confirmable and have not arrived, a
> >>>   retransmit missing payloads response is needed.
> >>>> * "If there is insufficient space to create a response PDU": I don't
> >>>>   understand what that means. (Where are request options reflected
> >>>>   back?).
> >>> [Jon] This was triggered by a question by Michael Richardson " So,
> >>> given a Christmas-Tree-Packet (largest packet, every possible option
> >>> space used, every extension turned on...) how much data can I get
> >>> back? :-)" and not fully thought through.
> >>> It could happen though with Location-Path, Location-Query, Q-Block2,
> >>> ETag,
> >>> Size2 and possibly Maxage, Content-Type, Hop-Limit or OSCORE  in
> >>> response to a POST.
> >>> OLD
> >>>    If there is insufficient space to create a response PDU with a block
> >>>    size of 16 bytes (SZX = 0) to reflect back all the request options as
> >>>    appropriate, a 4.13 (Request Entity Too Large) is returned without
> >>>    the Size2 Option.
> >>> NEW
> >>>    If there is insufficient space to create a response PDU with a block
> >>>    size of 16 bytes (SZX = 0) to send back all the response options as
> >>>    appropriate, a 4.13 (Request Entity Too Large) is returned without
> >>>    the Size1 Option.
> >>>
> >>>> * "If the client requests missing blocks, this is treated as a new
> >>>>    request.": I don't think the client should even make these follow-up
> >>>>    requests Observe, as it already has an ongoing observation. They'd be
> >>>>    sent on a different token too, so setting Observe would be opening
> >>>>    observation up on that token, which AFAIU is not intended. (Figure 7
> >>>>    example looks good to me in that respect.)
> >>>>
> >>>>    (It may make sense to ask the client to keep Observe to make the
> >>>>    requests matchable just for the sake of staying in atomic-request
> >>>>    mode. Either way, the server should then not accept that observation
> >>>>    as it's not for a block 0.)
> >>> [Jon] The intent here was that just a new Token should be used.
> >>> OLD
> >>>    If the client requests missing blocks, this is treated as a new
> >>>    request.  The Observe value may change but MUST still be reported.
> >>>    If the ETag value changes then the previously received partial body
> >>>    should be destroyed and the whole body re-requested.
> >>> NEW
> >>>    If the client requests missing blocks, this is treated as a new
> >>>    Request and the Observe Option MUST NOT be included.   If the ETag
> >> value
> >>> changes, then the previously received partial body
> >>>    should be considered as not fresh and the whole body re-requested.
> >>>
> >>>> * "First is CBOR encoded Request-Tag": Why? Each 4.08 response can
> be
> >>>>   matched by the token to a unique request that already had a
> >>>>   Request-Tag, and the client needs to have kept that token around
> >>>>   matched to the transfer to make sense of it.
> >>>>
> >>>>   No need to move that value around between subsystems, and just
> >>>>   dropping it from here would also remove the need for the "If the
> >>>>   client does not recognize the Request-Tag" clause (which would
> >>>>   otherwise need clarification as to what it'd mean if it recognizes it
> >>>>   but it doesn't match what the request was for).
> >>> [Jon] Good question - it does make sense for the Request-Tag to be
> >>> tracked alongside the Token in the client.
> >>> OLD
> >>>    The data payload of the 4.08 (Request Entity Incomplete) Response
> >>>    Code is encoded as a CBOR Sequence [RFC8742].  First is CBOR encoded
> >>>    Request-Tag followed by 1 or more missing CBOR encoded missing
> block
> >>>    numbers.
> >>> NEW
> >>>    The data payload of the 4.08 (Request Entity Incomplete) response
> >>>    is encoded as a CBOR Sequence [RFC8742].  There are one or more
> >> missing
> >>>    CBOR encoded missing block numbers.
> >>>
> >>> OLD
> >>>        ; This defines an array, the elements of which are to be used
> >>>        ; in a CBOR Sequence:
> >>>        payload = [request-tag, + missing-block-number]
> >>>        request-tag = bstr
> >>>        ; A unique block number not received:
> >>>        missing-block-number = uint
> >>> NEW
> >>>        ; This defines an array, the elements of which are to be used
> >>>        ; in a CBOR Sequence:
> >>>        payload = [+ missing-block-number]
> >>>        request-tag = bstr
> >>>        ; A unique block number not received:
> >>>        missing-block-number = uint
> >>>
> >>> OLD
> >>>    A 4.08 (Request Entity Incomplete) Response Code returned with
> >>>    Content-Type "application/missing-blocks+cbor-seq" indicates that
> >>>    some of the payloads are missing and need to be resent.  The client
> >>>    then re-transmits the missing payloads using the Request-Tag and
> >>>    Q-Block1 to specify the block number, SZX, and M bit as appropriate.
> >>>    The Request-Tag value to use is determined from the payload of the
> >>>    4.08 (Request Entity Incomplete) Response Code.  If the client does
> >>>    not recognize the Request-Tag, the client can ignore this response.
> >>> NEW (option presentation has been reformatted)
> >>>   4.08 (Request Entity Incomplete)
> >>>
> >>>   This Response Code returned with Content-Type "application/
> >>>   missing-blocks+cbor-seq" indicates that some of the payloads are
> >>> missing and need to be resent.  The client then retransmits the
> >>>   missing payloads using the same Request-Tag, Size1 and Q-Block1 to
> >>> specify the block number, SZX, and M bit as appropriate.
> >>>
> >>>
> >>>  The Request-Tag value to use is determined from the token in the
> >>>  4.08 (Request Entity Incomplete) response and then finding the
> >>> matching client request which contains the Request-Tag that is
> >>>   being used for this Q-Block1 body. END
> >>>> * "limit the array count to 23 (Undefined value)": 23 is the maximum
> >>>>   length of a zero-byte length indication, not indefinite-length (31).
> >>>>   Both using 23 and 31 here makes sense (up to 23 to have definite
> >>>>   length that can be updated in-place, or exceeding that switch to
> >>>>   indefinite length if they still fit), but the paragraph seems to be
> >>>>   mixing them up.
> >>> [Jon] OK
> >>> OLD
> >>>       Arrays (Section 3.2.2 of [RFC8949]), limit the array count to 23
> >>>       (Undefined value) so that the array data byte can be updated with
> >>>       the overall length once the payload length is confirmed or limited
> >>>       to MAX_PAYLOADS count.
> >>> NEW
> >>>       Arrays (Section 3.2.2 of [RFC8949]), or alternatively limit
> >>> the array count to
> >>>       23 so that the initial byte with the array major type and data
> >>> length in the additional information can be updated with the overall
> >>> count once the payload count is confirmed.  Further restricting the
> >>> count to MAX_PAYLOADS means that congestion control is less likely
> >>> to be
> >> invoked on the server.
> >>>> * "Each new request MUST use a unique token": Like above, this is
> >>>>   stating something that's not intended to be changed.
> >>> [Jon] RFC7252 does not require Tokens to be unique - e.g. empty
> >>> token values are acceptable.  Hence this statement.
> >>>> Congestion Control:
> >>>>
> >>>> * "Each NON 4.08 (Request Entity Incomplete) Response Codes is
> >> subjected
> >>>>    to PROBING_RATE.": That is unexpected here. At most one such
> >>>>    response is sent to each request message, so why is additional
> >>>>    congestion control needed?
> >>> [Jon] The intention here was that in the previous paragraph that it
> >>> was not the individual packets that are subject to PROBING_RATE, but
> >>> a single body comprising of multiple packets is subject to
> >>> PROBRING_RATE
> >>> - and hence limiting any individual responses to PROBING_RATE rather
> >>> than the potentially full set of responses OLD
> >>>    PROBING_RATE parameter in CoAP indicates the average data rate that
> >>>    must not be exceeded by a CoAP endpoint in sending to a peer
> endpoint
> >>>    that does not respond.  The body of blocks will be subjected to
> >>>    PROBING_RATE (Section 4.7 of [RFC7252]).
> >>> NEW
> >>>    PROBING_RATE parameter in CoAP indicates the average data rate that
> >>>    must not be exceeded by a CoAP endpoint in sending to a peer
> endpoint
> >>>    that does not respond.  The single body of blocks will be subjected to
> >>>    PROBING_RATE (Section 4.7 of [RFC7252]), not the individual packets.
> >>> If the wait time between sending bodies that are not being
> >>> responded to based on PROBING_RATE exceeds NON_PROBING_WAIT,
> >> then the
> >>>  gap time is limited to NON_PROBING_WAIT.
> >>>
> >>> Note: For the particular DOTS application, PROBING_RATE and other
> >>> transmission parameters are negotiated between peers.  Even when
> >>> not negotiated, the DOTS application uses customized defaults as
> >>> discussed in Section 4.5.2 of [RFC8782].
> >>> END
> >>>>    On the other hand, *ever* NON request is subject to PROBING_RATE,
> so
> >>>>    why point out the body of blocks and "GET or similar" particularly?
> >>> [Jon] It is only GET or FETCH.  The intention here is to not request
> >>> bodies of data at too high a rate.
> >>> OLD
> >>>    Each NON GET or similar request using Q-Block2 Option is subjected to
> >>>    PROBING_RATE.
> >>> NEW
> >>>    Each NON GET or FETCH request using Q-Block2 Option is subjected
> >>> to PROBING_RATE.
> >>>> * "a delay is introduced of ACK_TIMEOUT": As I understand
> >> MAX_PAYLOADS,
> >>>>   this is (rather implicitly) introduced as the package count up to
> >>>>   which it is OK to exceed PROBING_RATE temporarily (but after that it
> >>>>   kicks in all the harder by requiring to wait until complete-sent-bytes
> >>>>   over PROBING_RATE has expired). If that holds, at that time a much
> >>>>   larger delay than just ACK_TIMEOUT is needed to get a response from
> >>>>   the server: About 3 hours (see later note on parameters).
> >>> [Jon] Now limited to 247 seconds (NON_PROBING_WAIT).  See re-write
> >>> of Congestion Control section.
> >>>>   This is the crucial point in the document, and for it a recommendation
> >>>>   alone is not good enough. The protocol can be run with a vastly
> >>>>   increased PROBING_RATE (however externally determined) and from
> >> the
> >>>>   point of MAX_PAYLOADS just observe it. Or it has to get feedback
> from
> >>>>   the server; a single 4.08 is probably enough to kick off another
> >>>>   vollley of blocks. (How many? MAX_PAYLOADS for every response?).
> >>>>   Both can be permitted, but just waiting ACK_TIMEOUT isn't doing any
> >>>>   good.
> >>> [Jon] See re-write of Congestion Control section where things should
> >>> now be simpler and more logical.  There is an introduction of new
> >>> variable definitions.
> >>>> * "For NON transmissions": This seems to imply that the full exchange
> of
> >>>>   a body is either NON or CON; I don't see where that'd come from. I'd
> >>>>   have expected to read something like "Each individual request can be
> >>>>   NON or CON independent of the others. In particular, it can be
> >>>>   convenient to send the ultimate payload...".
> >>> [Jon]The DOTS environment will only be using NON.  To make
> >>> Congestion Control simple, the expectation is that all transmissions
> >>> are NON or (not recommended) are all CON. The draft now generally
> >>> records this expectation.
> >>>> * "If a Confirmable packet is used, then the transmitting peer MUST
> wait
> >>>>   for the ACK": Why? A NSTART > 1 would give it leisure to still
> >>>>   transmit.
> >>> [Jon] Text has been removed in the clean-up.
> >>>> * General on congestion control: It may help implementors if this were
> >>>>   split up into newly introduced rules and concepts (that is,
> >>>>   MAX_PAYLOADS and the answer to whether you may send
> >> MAX_PAYLOADS en
> >>>>   block again after having only even one response from the last round,
> >>>>   and probably the recommended parameters of the "Also on
> >> parameters"
> >>>>   comment), and another subsection on how Q-Block behaves well
> when
> >>>>   observing these.
> >>> [Jon] Should now be covered in the updated Congestion Control
> section.
> >>>> Caching:
> >>>>
> >>>> * "are not part of the cache key": How about "are removed as part of
> the
> >>>>   block assembly and thus do not reach the cache"?
> >>> [Jon] OK.
> >>> OLD
> >>>    As the entire body is being cached in the proxy, the Q-Block1 and
> >>>    Q-Block2 Options are not part of the cache key.
> >>> NEW
> >>>    As the entire body is being cached in the proxy, the Q-Block1 and
> >>>    Q-Block2 Options are removed as part of the block assembly and
> >>> thus do not reach the cache.
> >>>> * "When the next client completes building the body": If the proxy
> >>>>   chooses not to let them happen in parallel (which it may, see above
> on
> >>>>   parallel requests, although the server might still not support it and
> >>>>   cancel one of them), why bother letting the first finish just to abort
> >>>>   it? (IOW: If the proxy does not intend to see both through, which it
> >>>>   could if it held back the second until the first is through on the
> >>>>   uplink, it could just as well err out of one of them early, but it may
> >>>>   also rather see both through.)
> >>> [Jon] It has to be assumed that traffic to/from the origin client
> >>> and origin server may not both support Q-Blockx and potentially may
> >>> have a different SZX.  Thus passing a request or a response through
> >>> at the block level introduces a new set of challenges (but not
> >>> impossible to fix).  To keep this simple, my thinking was that the
> >>> passing through can only take place at the body level.  Again, the
> >>> arrival of packets is not necessarily sequential, so client A's body
> >>> may start transmitting to the origin server first, but client B's
> >>> body starts to arrive first - the same being true for the proxy as a
> >>> client may stop transmitting for whatever reason (restart, network loss
> etc.).
> >>> However this is covered by the above update "  If a server receives
> >>> payloads with different Request-Tags for the same resource, it
> >>> should
> >> continue to process all the bodies".
> >>> OLD
> >>>    and the new body representation transmission starts with a new
> >>>    Request-Tag value.
> >>> NEW
> >>>    and the new body representation transmission starts with a new
> >>>    Request-Tag value.  Note that it cannot be assumed that the proxy
> >>> will always receive a complete body from a client.
> >>>> * Examples:
> >>>>
> >>>>   * Figure 5: The ... between e3 request and response indicate the
> >>>>     MAX_TRANSMIT_SPAN before sending the 4.08 response. I suppose
> >> there
> >>>>     should be the same kind of delay between the failed e5 transmission
> >>>>     and the e4 response.
> >>> [Jon] Agreed and added in
> >>>>   * If the second burst had 3 requests out of which 2 made it, is there
> >>>>     any guidance for which of them the 4.08 would come back on? (In the
> >>>>     end, none of them is terminal).
> >>> [Jon] The client should tracking all Tokens of the burst (hence
> >>> implementation note about bottom 32bits unique and top 32 bits
> >>> matching block number for ease of tracking) for a response and so it
> >>> will make no difference at to which token is used for the 4.08
> >>> response.  From an implementation perspective, it probably is easier
> >>> to track the last opaque token that has the same Request-Tag.
> >>> OLD
> >>>    missing ones in one go (Figure 5).  It does so by indicating which
> >>>    blocks have been received in the data portion of the response.
> >>> NEW
> >>>    missing ones in one go (Figure 5).  It does so by indicating which
> >>>    blocks have been received in the data portion of the response.
> >>> The Token just needs to be one of those that have been received for
> >>> this Request-Tag , so the client can derive the Request-Tag.
> >>>>   * If that e4 response gets lost, does the whole mechanism recover
> from
> >>>>     it in any way?
> >>> [Jon] In this example, if e4 and e5 get lost, there will be no
> >>> 4.08/2.01/2.04/5.xx etc. response, so it is up to the client as to
> >>> whether it sends the request again or gives up.  See 9.1
> >>>   "Under high levels of traffic loss, the client can elect not to retry
> >>>    sending missing blocks of data.  This decision is implementation
> >>>    specific."
> >>>>     Generally, the all-NON and all-CON examples don't look to me like
> >>>>     what I'd be doing with this spec; the mixed "a CON every
> >>>>     MAX_PAYLOADS" appears much more realistic.
> >>> [Jon] It is unsafe to use CON in the  (potentially lossy) DOTS
> >>> environment (up to 93 secs timeout per payload with the defaults).
> >>> Hence why we are separating out the NON / CON usage.
> >>>>   * Figure X: The request ahs M unset and thus indicats a request for
> >>>>     just that block. If more than one is expected, it should say
> >>>>     QB2:0/1/1024.
> >>> [Jon] With Figure 7, with the M bit set, block 3 would get returned
> >>> for a second time.  Draft-ietf-core-new-block-03 also has a Figure 8
> >>> which does exactly what you describe.
> >>>> * New Content Format: I think this needs a media type registration to
> go
> >>>>   with it first; based on that, a content format can be registered.
> >>> [Jon] Med has responded to this and draft updated.
> >>>> * General on MAX_TRANSMIT_SPAN and other timing parameters: I'm
> not
> >>>> sure
> >>>>   they're 1:! applicable here. For example, MAX_TRANSMIT_SPAN is
> >> defined
> >>>>   in terms of reliable transmission, but used for NONs as well. (So is
> >>>>   the alternative ot 2x ACK_TIMEOUT).
> >>> [Jon] I hear you about the use of MAX_TRANSMIT_SPAN and
> ACK_TIMEOUT
> >> in
> >>> a NON environment. Hence re-write of Congestion Control section
> >>> defining new variables that can be used for NON.
> >>>>   For the purpose of delaying a 4.08 or a follow-up GET, it may make
> >>>>   more sense to define a new parameter based on MAX_LATENCY and
> the
> >>>> time
> >>>>   it takes the sender to pump out the options (which I don't think we
> >>>>   have a good factor for, but may even be negligible here).
> >>>>
> >>>>   Could read like this:
> >>>>
> >>>>   > The timing parameter MAX_BLOCK_JITTER is introduced, and by
> >> default
> >>>>   > takes a value of MAX_LATENCY + MAX_PAYLOADS * MTU /
> >> BANDWIDTH.
> >>> [Jon]  Lets plug in some numbers here.  MAX_LATENCY = 100,
> >>> MAX_PAYLOADS = 10, MTU = 1280bytes and BANDWIDTH = 1Mbps.
> >>>
> >>> [Jon] MAX_BLOCK_JITTER = 100 + (10 * 1280 * 8)/(1 000 000) = 100.1.
> >>> So BANDWITH of 1Mbps has negligible effect on the calculation. 1Kbps
> >>> makes MAX_BLOCK_JITTER 200 seconds.
> >>>>   >
> >>>>   > With Q-Block2, a client can ask for any missing blocks after not
> >>>>   > having received any further response for the duration of
> >>>>   > MAX_BLOCK_JITTER.
> >>> [Jon] 100+ seconds delay is way too much time to wait for any
> >>> missing blocks in my opinion.
> >>>
> >>> [Jon] RFC7252 also states (and the intention is that recovery works
> >>> well) " as MAX_LATENCY is not
> >>>       intended to describe a situation when the protocol works well, but
> >>>       the worst-case situation against which the protocol has to guard."
> >>>>   >
> >>>>   > With Q-Block1, a server holds off any response for
> MAX_BLOCK_JITTER
> >>>>   > unless all blocks have been received. Only then it evaluates
> whether
> >>>>   > to respond with a 2.0x code, a 4.08 with payload, or not at all
> >>>>   > (because it responded to a later request).
> >>> [Jon] I am not convinced that this is necessarily the way to go.
> >>> The new Congestion Control more cleanly handles this.
> >>>>   This also brings me back to the earlier matter of 2.31: What is a
> >>>>   server supposed to send when no packages were lost, but it's pasing
> >>>>   the timeout and wants to help the client flush out more packages by
> >>>>   confirming something? It says 4.08 in 3.3, but it's not like there's a
> >>>>   hole in the contiguous range. Does it need to send 4.08 enumerating
> >>>>   all (or at least some) numbers between the first unreceived and
> what's
> >>>>   indicated by Size1? Or can it just send 2.31 and the client knows all
> >>>>   it needs to know b/c the response came to the largest block that was
> >>>>   sent and 2.31 indicates that everything is good up to that point?
> >>> [Jon] The previous draft states (under Congestion Control) that the
> >>> client waits for ACK_TIMEOUT before transmitting the next set of
> >>> MAX_PAYLOADS blocks.  The server should wait for "two times
> >>> ACK_TIMEOUT " (3.3) before indicating issue.  Apart from perhaps
> >>> having a new name for ACK_TIMOUT I think that these are reasonable
> >>> values for Non-Confirmable - and are used in the new Congestion
> >>> Control
> >> section.
> >>> [Jon] I have reworked Congestion Control to use 2.31 (NON only) as a
> >>> signal to say that all of the current MAX_PAYLOADS payloads of a
> >>> body have been received, so allowing the client to continue
> >>> transmitting the next set of MAX_PAYLOADS payloads without the need
> >>> to wait any
> >> longer.
> >>>> * Also on parameters: This document is describing flow control stuff
> >>>>   around a situation CoAP was not originally designed for. Wouldn't it
> >>>>   make sense to include a set of parameters (PROBING_RATE,
> >> MAX_LATENCY,
> >>>>   ACK_TIMEOUT) that's suitable for the DOTS use case? I doubt that
> >>>>   PROBING_RATE will be left to 1 byte/second for any DOTS application
> >>>>   using this (for sending 10KiB in the initial 10-package MAX_PAYLOADS
> >>>>   burst would mark that connection as unusable for about 3 hours if
> they
> >>>>   all get lost), so better give justifiable numbers here than rely on
> >>>>   implemnetors to come up with unreviewed numbers or disregard
> >>>>   PROBING_RATE altogether.
> >>> [Jon] Answered by Med, and some new text added.
> >>>>   I don't know if it needs additional justification, but an increased
> >>>>   N_START may be justifiable there.
> >>> [Jon] It may be, but tuning the other associated parameters is
> >>> really out of the cope of this draft. This text has been added NEW
> >>> Congestion control for CON requests and responses is specified in
> >>> Section 4.7 of [RFC7252].  For faster transmission rates, NSTART will
> >>>   need to be increased from 1.  However, the other CON congestion
> >>>   control parameters will need to be tuned to cover this change.  This
> >>>   tuning is out of scope of this document as it is expected that all
> >>>   requests and responses using Q-Block1 and Q-Block2 will be Non-
> >>>   confirmable.
> >>>> * Somewhere (never comes up but I think it should): When CONs are
> >> used,
> >>>>   a 4.08 (or 2.31?) response to a later request can indicate to the
> >>>>   client that an earlier CON request has been processed successfully. If
> >>>>   the client can match that up (and it should be able to), then it can
> >>>>   (and should) cancel that particular CON request.
> >>> [Jon] I think that this is covered by my update above with the text "
> >>> NEW
> >>>    For Confirmable transmission, the server continues to acknowledge
> >>>   each packet, but a response is not required (whether separate or
> >>>   piggybacked) until successful receipt of the body or, if some of the
> >>>   payloads are sent as Non-confirmable and have not arrived, a
> >>>   retransmit missing payloads response is needed."
> >>>
> >>> And in my previous part 1 response (updated) NEW For Confirmable
> >>> transmission, the server continues to acknowledge  each packet, but
> >>> a response is not required (whether separate or
> >>>  piggybacked) until successful receipt of the body or, if some of the
> >>>   payloads are sent as Non-confirmable and have not arrived, a
> >>>   retransmit missing payloads response is needed.
> >>>> Best regards
> >>>> Christian
> >>>>
> >>>> --
> >>>> There's always a bigger fish.
> >>>>   -- Qui-Gon Jinn
> >>> _______________________________________________
> >>> core mailing list
> >>> core@ietf.org
> >>>
> >>
> https://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fww
> >> w.
> >>
> ietf.org%2Fmailman%2Flistinfo%2Fcore&amp;data=04%7C01%7Cmarco.tiloc
> >> a%4
> >>
> 0ri.se%7C52440c4d23e244168b2108d8b2574780%7C5a9809cf0bcb413a838a09
> >> ecc4
> >>
> 0cc9e8%7C0%7C0%7C637455435959417764%7CUnknown%7CTWFpbGZsb3d8
> >> eyJWIjoiMC
> >>
> 4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&
> >> amp;sd
> >>
> ata=tEJ8tHhaLeWl4dtblsDzyli5TBSmfnRTxdepcwxhYzY%3D&amp;reserved=0
> >>
> >> --
> >> Marco Tiloca
> >> Ph.D., Senior Researcher
> >>
> >> RISE Research Institutes of Sweden
> >> Division ICT
> >> Isafjordsgatan 22 / Kistagången 16
> >> SE-164 40 Kista (Sweden)
> >>
> >> Phone: +46 (0)70 60 46 501
> >>
> https://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fww
> w
> >>
> .ri.se%2F&amp;data=04%7C01%7Cmarco.tiloca%40ri.se%7C2385ef89ef574a7
> c8
> >>
> 1f608d8b3da00ba%7C5a9809cf0bcb413a838a09ecc40cc9e8%7C0%7C0%7C637
> 45709
> >>
> 6666457035%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIj
> oiV2luMz
> >>
> IiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&amp;sdata=iJgJcxZmwbaLrb
> mzIuz
> >> SjezxDRq47wwWcNvFC7ox8bw%3D&amp;reserved=0
> >>
> >
> 
> --
> Marco Tiloca
> Ph.D., Senior Researcher
> 
> RISE Research Institutes of Sweden
> Division ICT
> Isafjordsgatan 22 / Kistagången 16
> SE-164 40 Kista (Sweden)
> 
> Phone: +46 (0)70 60 46 501
> https://www.ri.se
>