Change:
length it is requesting. Upon receiving the ADDRESS_REQUEST capsule, an endpoint SHOULD assign <del> an IP address to its peer, and then respond with an ADDRESS_ASSIGN capsule to inform the peer of the assignment.  Note that the receiver of the ADDRESS_REQUEST capsule is not required to assign the requested address, and that it can also assign some requested addresses but not others. </del> <ins> one or more IP addresses to its peer, and then respond with an ADDRESS_ASSIGN capsule to inform the peer of the assignment.  For each Requested Address, the receiver of the ADDRESS_REQUEST capsule SHOULD respond with a Assigned Address with a matching Request ID. If the requested address was assigned, the IP Address and IP Prefix Length fields in the Assigned Address response SHALL be set to the assigned values.  If the requested address was not assigned, the IP Address SHALL be all-zero and the IP Prefix Length SHALL be the maximum length (0.0.0.0/32 or ::/128) to indicate that no address was assigned.  Note that other Assigned Address entries that do not correspond to any Request ID can also be contained in the same ADDRESS_ASSIGN response. </ins> If an endpoint receives an ADDRESS_REQUEST capsule that contains zero Requested Addresses, it MUST abort the IP proxying request stream.

Discussion:
IIUC the recipient of an ADDRESSREQUEST has to respond one way or another, using ADDRESSASSIGN. Via , it is possible to reject a request and send a "null response" back. Per ADDRESSASSIGN Technically, the address was never given, so sending a "null address" just once and then never sending it again is probably a good move - it limits the commitment to remember full details and reduces capsule transfer size. Endpoints that try to send a complete list of addresses in every ADDRESSASSIGN, including the null ones, might find they could get aboused, because its a lot simpler to send a short request with a unique request ID, than to respond to it. Probably nothing needs to change in the protocol but adding some considerations for implementers might be nice.
That's fair, we should say that the all-zero addresses don't need to be repeated in future capsules
Preferences for SHOULD NOT be repeated vs MUST NOT be repeated?
If an endpoint sends a polite ADDRESS_REQUEST that is well formed but the receiver can't or won't action it, there's no feedback. Since capsules are sent reliably, we can depend on them making it to the peer, but not necessarily being procesed. If the request is blackholed, should it, for example, ever be retried? There's a difference between a proxy refusing to do something and it temporarily being unable to do it (possibly due to resource constraints or rate limiting).
I don't think we currently have support for an ADDRESS_REQUEST capsule not being replied-to. The current language is written with the expectation that every REQUEST gets a RESPONSE. SO I would expect that if the request cannot be satisfied (i.e., is rejected) you get the rejection response that NAME just committed. So I would expect a proxy that is being rate-limited to respond, just slowly.
NAME please see URL
Thanks! makes it clearer how to assertively respond, which is good. However, the text IP addresses to its peer, and then respond with an ADDRESSASSIGN capsule to inform the peer of the assignment. This SHOULD is a bit hairy. Maybe it would be clear to split these out and state that a receiver of an ADDRESSREQUEST MUST reply.
I agree, I think that this should be upgraded to MUST that was missed after request/response IDs were added.
Agreed.

I'd be supportive of a MUST along the lines of: Though we need to wordsmith it better
Not sure if a MUST really helps here. I guess there is no way to force an endpoint to reply and we also can't specify until when the reply needs to come, so you always need to implement a logic to detect that you didn't get reply. To be honest that also a point where I'm not fully happy with . So far my assumption was rather that you can of course nicely ask for an address. But as soon as you get an address_assign you should assume that the list is complete and work with rather that than speculatively waiting for a potentially update that may or may not come. Sending a reject as specified in makes the situation less ambiguous but in the end it shouldn't really change much because it always better to start sending quickly with an address that you got assigned than to wait and hope for another address.
Why not? Peer could reset the stream, or time out the entire connection. That is what the point of a MUST is.
If you get a bunch of addresses assigned that you don't want to use and they're decide to not use the connect, I guess you should close it. however, if you use it, there is no point in closing it just because you didn't get a reply to your request. And again we don't send when a reply should or must be send. So there is no final deadline when you could close a stream.
The whole reason we added request IDs was to remove the requirement to timeout. This does not work if we allow the peers to simply not respond. The contract here needs to be that reach request gets a response, like HTTP. If a peer breaks that, you close the stream -- like HTTP.
I don't think it's the same. If you send two requests which each one IP address and you only get one reply, you can use the IP you got and everything is fine. In http if you don't get a reply, you connection simply broken. Yes, it would make things easier if you can guarantee that you always get a reply but I don't think there is a good way to enforce that; or even trying to enforce it, creates more limitation than it might help.
I think its easier to built a client if it knows whether to expect responses in the protocol or not.

This will govern how it approaches cases where it does or does not get a timely response, for some measure of timely. These might be (and probably are) implementations choices that should be pointed out. There's lots of reasons a client might detect something was slow, when in fact it was serviced as fast as possible. Imagine I run a proxy that might, for reasons that are outside of its control, have delays servicing one address request out of a few. If clients are going to be "smart" and make opaque decisions, then it could adversely affect my operations.
I've been noodling a bunch of scenarios where I think the draft could use a bit more clarification, and maybe a rev of the wire format around Request IDs for / . They largely fall under the question of how does an endpoint NAK an address request? The draft says an endpoint receiving an capsule SHOULD respond with an capsule, so I suppose not responding is allowed, but figuring out how to respond with a NAK is worthwhile. For this, I'm going to use the term client to refer to the party requesting addresses/prefixes, and server to refer to the party assigning addresses/prefixes. 1) The client has received an (unsolicited?) address. The client then requests a different address. The server has chosen to not assign that address. A suggestion I've heard: server sends capsule with existing assignment and new request's Request ID. 2) The client sends a capsule requesting multiple addresses The server has chosen to only assign a subset of those addresses (or a different address). Using the suggestion from (1) involves replying with sufficiently many capsules so as to exhaust the Request IDs sent. Maybe this means sending back n capsules all with the same one assignment, or n/2 capsules with the same two assignments, etc? 3) The client sends a capsule requesting an IP version not supported by the server. This could be a request for addresses for IPv4 and IPv6 from a server that supports only one, or a simpler case of asking for an IPv4 address from an IPv6-only server. It feels odd to use the suggestion from (1) to respond to a request for an IPv4 address with an IPv6 address or vice versa.

An alternative, which requires a wire format revision, is to include a list of NAK'd Request IDs in the capsule, which could be as simple as a varint count of IDs, followed by that many more varints. In the happy path, this is just one extra byte in the capsule.
Thanks for filing this NAME I agree that the draft isn't currently clear enough on how to respond to these scenarios. The three options I see are: do nothing write some text to explain how to use the existing capsule formats to indicate a rejected address request add a list of rejected request IDs to the ADDRESS_ASSIGN capsule Of these I think we really should avoid (1) because that could lead to interoperability issues, but I'm ok with either (2) or (3). I think I prefer (3) because changing the wire format now isn't too high of a cost and I think it'll make the protocol more explicit.
I agree we should do something here. Between (2) and (3), I'm not sure. We could fairly easily just say that if you include an with a non-zero Request ID but the assigned address is all zeros with a prefix length of 32 or 128, you're assigning an empty address, which is a rejection. Arguably, client must handle receiving such a capsule response anyway, and treat it as "no address assigned for that request". This is option (2), I think. If we do something like option (3), we'd have a field in the main ADDRESSASSIGN capsule for a list of rejected IDs, which would likely need to have a length in front, so we'd now have a field of at least a byte in all ADDRESSASSIGN capsules (even ones with no rejections) to handle the possibility of rejections. We either have a case where a lot of rejections leads to a somewhat bloated capsule, but the happy cases are nice and concise, or a case that optimizes for lots of rejections and always adds a byte to the happy cases. I personally prefer (2) there, since it only gets ugly if a ton of requests are being made anyhow. Thoughts NAME ?
I like your proposal NAME if we add text saying that 0.0.0.0/32 and ::/128 mean "your request was rejected" then we get the explicit property without changing the wire format.

That works for me.
It's also good because it doesn't have two ways of saying the same thing, since we'll need to handle 0.0.0.0/32 and ::/128 anyhow. I can try to write that up.
I appreciate the added symmetry that comes from giving the zero addresses specific meaning in both requests and assignments, and no wire format changes + no ambiguity is a win. LGTM.
Thanks!