@@ -30,7 +30,7 @@ func ConntrackGetActualDestination(src, dst netaddr.IPPort) (netaddr.IPPort, err
3030 sport := src .Port ()
3131 dport := dst .Port ()
3232
33- con := conntrack.Con {
33+ req := conntrack.Con {
3434 Origin : & conntrack.IPTuple {
3535 Src : & sip ,
3636 Dst : & dip ,
@@ -45,16 +45,43 @@ func ConntrackGetActualDestination(src, dst netaddr.IPPort) (netaddr.IPPort, err
4545 if dst .IP ().Is6 () {
4646 family = conntrack .IPv6
4747 }
48- sessions , err := conntrackClient .Get (conntrack .Conntrack , family , con )
48+ sessions , err := conntrackClient .Get (conntrack .Conntrack , family , req )
4949 if err != nil {
5050 return netaddr.IPPort {}, err
5151 }
5252 for _ , s := range sessions {
53- if s .Reply != nil && s .Reply .Src != nil && s .Reply .Proto != nil && s .Reply .Proto .SrcPort != nil {
54- ip , _ := netaddr .FromStdIP (* s .Reply .Src )
55- port := * s .Reply .Proto .SrcPort
56- return netaddr .IPPortFrom (ip , port ), nil
53+ if ! ipTupleValid (s .Origin ) || ! ipTupleValid (s .Reply ) {
54+ continue
5755 }
56+ var reply * conntrack.IPTuple
57+ if ipTuplesEqual (req .Origin , s .Origin ) {
58+ reply = s .Reply
59+ } else if ipTuplesEqual (req .Origin , s .Reply ) {
60+ reply = s .Origin
61+ }
62+ if reply == nil {
63+ continue
64+ }
65+ ip , _ := netaddr .FromStdIP (* reply .Src )
66+ port := * reply .Proto .SrcPort
67+ return netaddr .IPPortFrom (ip , port ), nil
5868 }
5969 return netaddr.IPPort {}, nil
6070}
71+
72+ func ipTuplesEqual (a , b * conntrack.IPTuple ) bool {
73+ return a .Src .Equal (* b .Src ) && a .Dst .Equal (* b .Dst ) && * a .Proto .SrcPort == * b .Proto .SrcPort && * a .Proto .DstPort == * b .Proto .DstPort
74+ }
75+
76+ func ipTupleValid (t * conntrack.IPTuple ) bool {
77+ if t == nil {
78+ return false
79+ }
80+ if t .Src == nil || t .Dst == nil || t .Proto == nil {
81+ return false
82+ }
83+ if t .Proto .SrcPort == nil || t .Proto .DstPort == nil {
84+ return false
85+ }
86+ return true
87+ }
0 commit comments