omniti-labs/Net--RabbitMQ — Issue #12: Protocol failures
Author: alexrj
Created: 2012-01-17 13:28:08+00:00
State: open

Hello, using RabbitMQ server 2.7.1 I am getting failures when enabling heartbeat. If I set to, say, 30 seconds, my consumer daemon dies with the following message:

```
Bad frame read. at /opt/ed-test/notarok/bin/../../common/lib/ED/App/Daemon/MessageConsumer.pm line 98.
```

I tried to capture the traffic using Wireshark, and it appears that the failure happens when the server sends the third heartbeat while connection is inactive.

I forked Net::RabbitMQ from GitHub to contribute a patch, but then I found more problems. It appears that when using Net::RabbitMQ, the server sends a malformed Channel.Open-Ok response. The RabbitMQ Tracer dies on it:

```
1326806094072: ch#0 <- {#method(version-major=8, version-minor=0, server-properties={product=RabbitMQ, information=Licensed under the MPL. See http://www.rabbitmq.com/, platform=Erlang/OTP, capabilities={}, copyright=Copyright (C) 2007-2011 VMware, Inc., version=2.7.1}, mechanisms=PLAIN AMQPLAIN, locales=en_US), null, "[B@67006d75"}
1326806094074: ch#0 -> {#method(client-properties={}, mechanism=PLAIN, response=guestguest, locale=en_US), null, "[B@67006d75"}
1326806094074: ch#0 <- {#method(channel-max=0, frame-max=131072, heartbeat=0), null, "[B@67006d75"}
1326806094108: ch#0 -> {#method(channel-max=0, frame-max=131072, heartbeat=30), null, "[B@67006d75"}
1326806094109: ch#0 -> {#method(virtual-host=/, capabilities=, insist=true), null, "[B@67006d75"}
1326806094149: ch#0 <- {#method(known-hosts=), null, "[B@67006d75"}
1326806094188: ch#1 -> {#method(out-of-band=), null, "[B@67006d75"}
1326806094231: uncaught java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at com.rabbitmq.client.impl.ValueReader.readBytes(ValueReader.java:86)
at com.rabbitmq.client.impl.ValueReader.readLongstr(ValueReader.java:103)
at com.rabbitmq.client.impl.ValueReader.readLongstr(ValueReader.java:111)
at com.rabbitmq.client.impl.MethodArgumentReader.readLongstr(MethodArgumentReader.java:73)
at com.rabbitmq.client.impl.AMQImpl$Channel$OpenOk.(AMQImpl.java:600)
at com.rabbitmq.client.impl.AMQImpl.readMethodFrom(AMQImpl.java:3242)
at com.rabbitmq.client.impl.CommandAssembler.consumeMethodFrame(CommandAssembler.java:93)
at com.rabbitmq.client.impl.CommandAssembler.handleFrame(CommandAssembler.java:158)
at com.rabbitmq.client.impl.AMQCommand.handleFrame(AMQCommand.java:87)
at com.rabbitmq.tools.Tracer$DirectionHandler.doFrame(Tracer.java:331)
at com.rabbitmq.tools.Tracer$DirectionHandler.run(Tracer.java:343)
at java.lang.Thread.run(Thread.java:636)
```

and Wireshark/tshark shows a *Malformed Packet* error:

```
0.000980 127.0.0.1 -> 127.0.0.1 AMQP Protocol-Header
0.001148 127.0.0.1 -> 127.0.0.1 AMQP Connection.Start
0.001303 127.0.0.1 -> 127.0.0.1 AMQP Connection.Start-Ok
0.001405 127.0.0.1 -> 127.0.0.1 AMQP Connection.Tune
0.001511 127.0.0.1 -> 127.0.0.1 AMQP Connection.Tune-Ok
0.031825 127.0.0.1 -> 127.0.0.1 AMQP Connection.Open
0.031946 127.0.0.1 -> 127.0.0.1 AMQP Connection.Open-Ok
0.032313 127.0.0.1 -> 127.0.0.1 AMQP Channel.Open
0.032770 127.0.0.1 -> 127.0.0.1 AMQP [Malformed Packet]
0.032822 127.0.0.1 -> 127.0.0.1 AMQP Tx.Select
0.032886 127.0.0.1 -> 127.0.0.1 AMQP Tx.Select-Ok
```

This **does not happen when using other client libraries** (such the Java client library), so I suspect there's something wrong in what the Net::RabbitMQ library sends, that causes the server to send a malformed answer.

I tried to check Net::RabbitMQ source code, but I was unable to find what's wrong. To recap, two issues:

* Channel.Open-Ok from server is malformed (but it isn't with other client libraries)
* enabling heartbeats causes the app to die with "Bad frame read"

I'm now reverting to my own Net::RabbitMQ::Java, but I'd love to use Net::RabbitMQ instead, so let me know your thoughts and how can I help about this issue.