You are viewing a plain text version of this content. The canonical link for it is here.
Posted to proton@qpid.apache.org by Bozo Dragojevic <bo...@digiverse.si> on 2013/11/03 17:41:27 UTC

The implicit reply_to address

Hi,

when I set message reply_to="~" the messenger changes that to 
"amqp://<name>" in outward_munge.

is such address format for addressing the container by name required by 
some AMQP spec or is this a messenger/proton specific feature?

for something like this:

   m = Messenger("www.google.com:80")
   msg = Message()
   msg.address = "amqp://127.0.0.1:12345"
   msg.reply_to = "~"
   m.send(1)
   sys.exit(0)

the reply_to will be amqp://www.google.com:80

The server from the testcase will *appear* to work, because the 
messenger is not given a chance
to notice connection teardown before it needs to resolve the reply_to 
address.

Apply the attached patch 0001-... and run:

# window 1 'server' that sends two replies to each request
$ PN_TRACE_FRM=1 ./recv -rr
# window 2 'google'
$ PN_TRACE_FRM=1 ./recv amqp://~127.0.0.1:23456/
# window 3 'client' with an unfortunate name that dies before it can 
receive the response
$ PN_TRACE_FRM=1 ./send -n127.0.0.1:23456 -rw

which forces server to send two replies, one by one and give the client 
the chance to go away.

I think it might be better for that address to read "amqp:///<name>" so 
that the 'magic' is signaled by empty domain which is otherwise not valid.

or maybe even "amqp:///~<name>/" so that it doesn't pollute the the 
'normal' part of the address namespace?

The attached patch 0002-... implements the former solution.

Now the server dies with:
recv.c:162: unable to connect to amqp:///127.0.0.1:23456: connect: 
Address family not supported by protocol family

The other beneficial effect of this change is that 'server' has no more 
sender links with null address which also solves the problem from my 
previous question.

Bozzo

Re: The implicit reply_to address

Posted by Bozo Dragojevic <bo...@digiverse.si>.
On 5. 11. 13 18:58, Rafael Schloming wrote:
> Hi,
>
> I'm scratching my head a bit to understand your scenario so I'll answer the
> easy question first. ;-) The address format currently used by messenger
> isn't part of any official spec, and the official spec will likely look a
> bit different. When the spec is ratified, we will have to change and
> probably do some work to maintain backwards compatibility.

in that case it's better to have just one backward compatibility problem 
instead of adding
another one on top.

> Now as for your scenario, I applied your patch and ran through the scenario
> you describe and what I observed was the first reply going from window 1 to
> window 3 getting dropped due to the (intentionally) aborted connection, and
> the second reply ending up going to window 2 because the window 1 messenger
> saw that there was no connection and was able to initiate its own
> connection based on the address in the reply_to. What is perhaps a little
> odd about this configuration is the fact that the messenger in window 3 has
> chosen a dns registered name that collides with the ip/port used in window
> 2. If you imagine instead that the messenger in window 3 is actually
> subscribed to  amqp://~127.0.0.1:23456/, then the behaviour could be quite
> useful. The server could in fact get a reply back to the client even if the
> client's original connection dies.
>
I fully admit the example is a bit contrieved. the ip-address name was 
to ease scenario setup
using the available bits and pieces.

> So assuming I understand your scenario/suggestion correctly, I'd say the
> ability to choose a dns registered name for your messenger is actually a
> feature, not a bug.

The bug part is this: only really simplistic applications will be able 
to respond to each request
immediately. As soon as there is any long-running processing (maybe 
sending and receiving
another amqp message) required to compute the reply it's much much 
easier to come to the
point where reply address will get intermittently interpreted as dns 
addresses.

>   I'll also point out that because the messenger name is
> placed in the reply_to address with simple text substitution, you can
> always choose your messenger name to be '/foo' instead of foo (or indeed
> you could use any illegal domain character) in order to avoid the
> possibility of accidental collision.
>
I like the "/foo" approach but '/' is not a good character as the 
resulting reply_to address gets mis-parsed.
try to get an actual reply:
$ ./recv -r & ./send -r -n /foo
...
recv.c:162: unable to connect to amqp:///foo: connect: Address family 
not supported by protocol family


Btw, starting the messenger name with "~" and a bit of bad luck will 
make the respondent start listening on a new port :)

"Don't do that then" is a good answer :)

Any other illegal domain character seems to fit the bill

here's a proposal for documentation change

---

diff --git a/proton-c/include/proton/message.h 
b/proton-c/include/proton/message.h
index 757b076..541cd46 100644
--- a/proton-c/include/proton/message.h
+++ b/proton-c/include/proton/message.h
@@ -86,6 +86,18 @@ PN_EXTERN const char *   
pn_message_get_subject           (pn_message_t *msg);
  PN_EXTERN int            pn_message_set_subject           
(pn_message_t *msg, const char *subject);

  PN_EXTERN const char *   pn_message_get_reply_to          
(pn_message_t *msg);
+/** Set the reply-to message property
+ *
+ * If the reply_to equals "~" or starts with "~/" then the reply_to
+ * will be rewritten when message is sent with pn_messenger_put(). The
+ * '~' is replaced with "amqp://<name>" where <name> is the name of
+ * the messenger used for sending.
+ *
+ * @param[in] msg the message to modify
+ * @param[in] reply_to the reply-to address
+ *
+ * @return 0 on success or a messenger error
+ */
  PN_EXTERN int            pn_message_set_reply_to          
(pn_message_t *msg, const char *reply_to);

  PN_EXTERN pn_data_t *    pn_message_correlation_id        
(pn_message_t *msg);
diff --git a/proton-c/include/proton/messenger.h 
b/proton-c/include/proton/messenger.h
index 5b318bf..f8f7e46 100644
--- a/proton-c/include/proton/messenger.h
+++ b/proton-c/include/proton/messenger.h
@@ -49,6 +49,13 @@ typedef enum {
  /** Construct a new Messenger with the given name. The name is global.
   * If a NULL name is supplied, a UUID based name will be chosen.
   *
+ * Note: See documentation for pn_message_set_reply_to for details how
+ * the name is used. Since the reply address will be re-interpreted by
+ * the responder make sure that the name does not accidentally resolve
+ * as a dns name or even starts with a "~" as that may lead to
+ * messages getting delivered to unexpected destination in certain
+ * edge cases. Name containing "/" should also be avoided.
+ *
   * @param[in] name the name of the messenger or NULL
   *
   * @return pointer to a new Messenger

---

Bozzo

Re: The implicit reply_to address

Posted by Rafael Schloming <rh...@alum.mit.edu>.
Hi,

I'm scratching my head a bit to understand your scenario so I'll answer the
easy question first. ;-) The address format currently used by messenger
isn't part of any official spec, and the official spec will likely look a
bit different. When the spec is ratified, we will have to change and
probably do some work to maintain backwards compatibility.

Now as for your scenario, I applied your patch and ran through the scenario
you describe and what I observed was the first reply going from window 1 to
window 3 getting dropped due to the (intentionally) aborted connection, and
the second reply ending up going to window 2 because the window 1 messenger
saw that there was no connection and was able to initiate its own
connection based on the address in the reply_to. What is perhaps a little
odd about this configuration is the fact that the messenger in window 3 has
chosen a dns registered name that collides with the ip/port used in window
2. If you imagine instead that the messenger in window 3 is actually
subscribed to  amqp://~127.0.0.1:23456/, then the behaviour could be quite
useful. The server could in fact get a reply back to the client even if the
client's original connection dies.

So assuming I understand your scenario/suggestion correctly, I'd say the
ability to choose a dns registered name for your messenger is actually a
feature, not a bug. I'll also point out that because the messenger name is
placed in the reply_to address with simple text substitution, you can
always choose your messenger name to be '/foo' instead of foo (or indeed
you could use any illegal domain character) in order to avoid the
possibility of accidental collision.

Does this help at all or do I have the wrong end of the stick regarding
your scenario?

--Rafael

On Sun, Nov 3, 2013 at 11:47 AM, Bozo Dragojevic <bo...@digiverse.si> wrote:

> On 3. 11. 13 17:41, Bozo Dragojevic wrote:
>
> [snip]
>
>  The attached patch 0002-... implements the former solution.
>>
>>
> I just noticed it's possible to say reply_to = "~/foo/bar". If the
> principle is sound I can supply the rest of needed changes.
>
> Bozzo
>

Re: The implicit reply_to address

Posted by Bozo Dragojevic <bo...@digiverse.si>.
On 3. 11. 13 17:41, Bozo Dragojevic wrote:

[snip]
> The attached patch 0002-... implements the former solution.
>

I just noticed it's possible to say reply_to = "~/foo/bar". If the 
principle is sound I can supply the rest of needed changes.

Bozzo