title: Unexpected HAPROXY acl behaviour tcp payload routing
body: <p>I am setting up simple tcp connection routing using HAProxy acl's. The idea is to route connections depending on request content having two flavors: read and write requests.</p>
  
  <p>For testing I made a simple tcp client/server setup using perl. Strangely enough about 10-40% of the ACL's fail and are sent to the default backend. </p>
  
  <p>The ACL's should find the substring 'read' or 'write' and route accordingly, but this is not allways the case.</p>
  
  <p>Sending a read/write request using nc (netcat) has the same effect.</p>
  
  <p>I tested this configuration with mode=http and everything works as expected. </p>
  
  <p>I also tested with reg, sub and bin, to no avail.</p>
  
  <p>The example server setup is as follows:</p>
  
  <ul>
  <li><p>HAProxy instance, listens on port 8000</p></li>
  <li><p>Client (creates tcp connection to proxy and sends user input (read/write string) to server through port 8000, after which it closes the connection)</p></li>
  <li><p>Server1 (write server), listens on port 8001</p></li>
  <li><p>Server2 (read server), listens on port 8002</p></li>
  <li><p>Server3 (default server), listens on port 8003</p></li>
  </ul>
  
  <p>My HAProxy configuration file looks is:</p>
  
  <pre><code>global
      log /dev/log    local0 debug
      #daemon
      maxconn 32
  
  defaults
      log global
      balance roundrobin
      mode tcp
      timeout connect 5000ms
      timeout client 50000ms
      timeout server 50000ms
  
  frontend tcp-in
      bind *:8000
      tcp-request inspect-delay 3s
  
      acl read req.payload(0,4) -m sub read
      acl write req.payload(0,5) -m sub write
  
      use_backend read_servers if read
      use_backend write_server if write
  
      default_backend testFault
  
  backend write_server
      server server1 127.0.0.1:8001 maxconn 32
  backend read_servers
      server server2 127.0.0.1:8002 maxconn 32
  backend testFault
      server server3 127.0.0.1:8003 maxconn 32
  </code></pre>
  
  <p>The client code (in perl):</p>
  
  <pre><code>use IO::Socket::INET;
  # auto-flush on socket
  #$| = 1;
  
  print "connecting to the server\n";
  
  while(&lt;STDIN&gt;){
  
  # create a connecting socket
  my $socket = new IO::Socket::INET (
  PeerHost =&gt; 'localhost',
  PeerPort =&gt; '8000',
  Proto =&gt; 'tcp',
  );
  
  die "cannot connect to the server $!\n" unless $socket;
  
      # data to send to a server
      $req = $_;
      chomp $req;
  
      $size = $socket-&gt;send($req);
      print "sent data of length $size\n";
  
      # notify server that request has been sent
      shutdown($socket, 1);
  
      # receive a response of up to 1024 characters from server
      $response = "";
      $socket-&gt;recv($response, 1024);
      print "received response: $response\n";
      $socket-&gt;close();
      }
  </code></pre>
  
  <p>The server (perl code):</p>
  
  <pre><code>use IO::Socket::INET;
  if(!$ARGV[0]){
      die("Usage; specify a port..");
  }
  # auto-flush on socket
  $| = 1;
  
  # creating a listening socket
  
  my $socket = new IO::Socket::INET (
  LocalHost =&gt; '0.0.0.0',
  LocalPort =&gt; $ARGV[0],
  Proto =&gt; 'tcp',
  Listen =&gt; 5,
  Reuse =&gt; 0
  );
  
  die "cannot create socket $!\n" unless $socket;
  print "server waiting for client connection on port $ARGV[0]\n";
  
  while(1){
  
  # waiting for a new client connection
  my $client_socket = $socket-&gt;accept();
  
  # get information about a newly connected client
  my $client_address = $client_socket-&gt;peerhost();
  my $client_port = $client_socket-&gt;peerport();
  print "connection from $client_address:$client_port\n";
  
  # read up to 1024 characters from the connected client
  my $data = "";
  $client_socket-&gt;recv($data, 1024);
  print "received data: $data\n";
  # write response data to the connected client
  $data = "ok";
  $client_socket-&gt;send($data);
  
  # notify client that response has been sent
  shutdown($client_socket, 1);
  $client_socket-&gt;close();
  print "Connection closed..\n\n";
  }
  
  $socket-&gt;close();
  </code></pre>