• Marco Angaroni's avatar
    ipvs: update real-server binding of outgoing connections in SIP-pe · 3ec10d3a
    Marco Angaroni authored
    Previous patch that introduced handling of outgoing packets in SIP
    persistent-engine did not call ip_vs_check_template() in case packet was
    matching a connection template. Assumption was that real-server was
    healthy, since it was sending a packet just in that moment.
    
    There are however real-server fault conditions requiring that association
    between call-id and real-server (represented by connection template)
    gets updated. Here is an example of the sequence of events:
      1) RS1 is a back2back user agent that handled call-id1 and call-id2
      2) RS1 is down and was marked as unavailable
      3) new message from outside comes to IPVS with call-id1
      4) IPVS reschedules the message to RS2, which becomes new call handler
      5) RS2 forwards the message outside, translating call-id1 to call-id2
      6) inside pe->conn_out() IPVS matches call-id2 with existing template
      7) IPVS does not change association call-id2 <-> RS1
      8) new message comes from client with call-id2
      9) IPVS reschedules the message to a real-server potentially different
         from RS2, which is now the correct destination
    
    This patch introduces ip_vs_check_template() call in the handling of
    outgoing packets for SIP-pe. And also introduces a second optional
    argument for ip_vs_check_template() that allows to check if dest
    associated to a connection template is the same dest that was identified
    as the source of the packet. This is to change the real-server bound to a
    particular call-id independently from its availability status: the idea
    is that it's more reliable, for in->out direction (where internal
    network can be considered trusted), to always associate a call-id with
    the last real-server that used it in one of its messages. Think about
    above sequence of events where, just after step 5, RS1 returns instead
    to be available.
    
    Comparison of dests is done by simply comparing pointers to struct
    ip_vs_dest; there should be no cases where struct ip_vs_dest keeps its
    memory address, but represent a different real-server in terms of
    ip-address / port.
    
    Fixes: 39b97223 ("ipvs: handle connections started by real-servers")
    Signed-off-by: default avatarMarco Angaroni <marcoangaroni@gmail.com>
    Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
    Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
    3ec10d3a
ip_vs.h 46.8 KB