github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/nfqdatapath/datapath_tcp.go (about)

     1  package nfqdatapath
     2  
     3  // Go libraries
     4  import (
     5  	"bytes"
     6  	"fmt"
     7  	"strconv"
     8  
     9  	"github.com/pkg/errors"
    10  	"go.aporeto.io/enforcerd/trireme-lib/collector"
    11  	"go.aporeto.io/enforcerd/trireme-lib/controller/constants"
    12  	enforcerconstants "go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/constants"
    13  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/claimsheader"
    14  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/connection"
    15  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/counters"
    16  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/packet"
    17  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/pucontext"
    18  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/tokens"
    19  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    20  	"go.uber.org/zap"
    21  )
    22  
    23  var (
    24  	errNonPUTraffic     = errors.New("not a pu traffic")
    25  	errNonPUUDPTraffic  = errors.New("not a pu udp traffic")
    26  	errOutOfOrderSynAck = errors.New("out of order syn ack packet")
    27  	errRstPacket        = errors.New("rst packet")
    28  	errNoConnection     = errors.New("no connection found")
    29  
    30  	// Custom ping error types
    31  	errDropPingNetSynAck = errors.New("net synack dropped")
    32  	errDropPingNetSyn    = errors.New("net syn dropped") // nolint: varcheck
    33  
    34  	rstIdentity = []byte("enforcerrstidentity")
    35  )
    36  
    37  // processNetworkPackets processes packets arriving from network and are destined to the application
    38  func (d *Datapath) processNetworkTCPPackets(p *packet.Packet) (*connection.TCPConnection, func(), error) {
    39  	var conn *connection.TCPConnection
    40  	var err error
    41  	var f func()
    42  
    43  	debugLogs := func(debugString string) {
    44  
    45  		if d.PacketLogsEnabled() {
    46  			zap.L().Debug(debugString,
    47  				zap.String("flow", p.L4FlowHash()),
    48  				zap.String("Flags", packet.TCPFlagsToStr(p.GetTCPFlags())),
    49  				zap.Error(err))
    50  		}
    51  	}
    52  
    53  	// Retrieve connection state of SynAck packets and
    54  	// skip processing for SynAck packets that we don't have state
    55  	switch p.GetTCPFlags() & packet.TCPSynAckMask {
    56  	case packet.TCPSynMask:
    57  		conn, err = d.netSynRetrieveState(p)
    58  		if err != nil {
    59  			switch err {
    60  			// Non PU Traffic let it through
    61  			case errNonPUTraffic:
    62  				return conn, nil, nil
    63  			default:
    64  				debugLogs("Packet rejected")
    65  				return conn, nil, err
    66  			}
    67  		}
    68  
    69  	case packet.TCPSynAckMask:
    70  		conn, err = d.netSynAckRetrieveState(p)
    71  		if err != nil {
    72  			switch err {
    73  			case errOutOfOrderSynAck:
    74  				// Drop this synack it is for a flow we know which is marked for deletion.
    75  				// We saw a FINACK and this synack has come without we seeing an appsyn for this flow again
    76  				return conn, nil, counters.CounterError(counters.ErrOutOfOrderSynAck, fmt.Errorf("ErrOutOfOrderSynAck"))
    77  			default:
    78  				d.releaseUnmonitoredFlow(p)
    79  				return conn, nil, nil
    80  			}
    81  		}
    82  
    83  	default:
    84  		conn, err = d.netRetrieveState(p)
    85  		switch err {
    86  		case nil:
    87  			// Do nothing.
    88  		case errRstPacket:
    89  			return conn, nil, nil
    90  		default:
    91  			debugLogs("Packet rejected")
    92  			return conn, nil, err
    93  		}
    94  	}
    95  
    96  	conn.Lock()
    97  	defer conn.Unlock()
    98  
    99  	if conn.GetState() == connection.TCPSynSend && p.GetTCPFlags()&packet.TCPRstMask != 0 && !conn.PingEnabled() {
   100  		p.TCPDataDetach(0)
   101  		d.cacheRemove(d.tcpClient, p.L4ReverseFlowHash())
   102  		return conn, f, nil
   103  	}
   104  
   105  	f, err = d.processNetworkTCPPacket(p, conn.Context, conn)
   106  	if err != nil {
   107  		debugLogs("Rejecting packet")
   108  		return conn, nil, err
   109  	}
   110  	return conn, f, nil
   111  }
   112  
   113  // processApplicationPackets processes packets arriving from an application and are destined to the network
   114  func (d *Datapath) processApplicationTCPPackets(p *packet.Packet) (conn *connection.TCPConnection, err error) {
   115  
   116  	debugLogs := func(debugString string) {
   117  		if d.PacketLogsEnabled() {
   118  			zap.L().Debug(debugString,
   119  				zap.String("flow", p.L4FlowHash()),
   120  				zap.String("Flags", packet.TCPFlagsToStr(p.GetTCPFlags())),
   121  				zap.Error(err),
   122  			)
   123  		}
   124  	}
   125  
   126  	switch p.GetTCPFlags() & packet.TCPSynAckMask {
   127  	case packet.TCPSynMask:
   128  		conn, err = d.appSynRetrieveState(p)
   129  		if err != nil {
   130  			debugLogs("Packet rejected")
   131  			return conn, err
   132  		}
   133  	case packet.TCPSynAckMask:
   134  		conn, err = d.appSynAckRetrieveState(p)
   135  		if err != nil {
   136  			debugLogs("SynAckPacket Ignored")
   137  			cid, err := d.contextIDFromTCPPort.GetSpecValueFromPort(p.SourcePort())
   138  
   139  			if err == nil {
   140  				item, err := d.puFromContextID.Get(cid.(string))
   141  				if err != nil {
   142  					// Let the packet through if the context is not found
   143  					return conn, nil
   144  				}
   145  
   146  				ctx := item.(*pucontext.PUContext)
   147  
   148  				// Syn was not seen and this synack packet is coming from a PU
   149  				// we monitor. This is possible only if IP is in the external
   150  				// networks or excluded networks. Let this packet go through
   151  				// for any of these cases. Drop for everything else.
   152  				_, policy, perr := ctx.NetworkACLPolicyFromAddr(p.DestinationAddress(), p.SourcePort(), p.IPProto())
   153  				if perr == nil && policy.Action.Accepted() {
   154  					ctx.Counters().IncrementCounter(counters.ErrSynAckToExtNetAccept)
   155  					return conn, nil
   156  				}
   157  
   158  				// Drop this synack as it belongs to PU
   159  				// for which we didn't see syn
   160  
   161  				// FYI.  This can happen when the enforcer is starting. The syn packet gets by the enforcer but is then caught here.
   162  				zap.L().Debug("Network Syn was not seen, and we are monitoring this PU. Dropping the syn ack packet", zap.String("contextID", cid.(string)), zap.Uint16("port", p.SourcePort()))
   163  				return conn, counters.CounterError(counters.ErrNetSynNotSeen, fmt.Errorf("Network Syn was not seen"))
   164  			}
   165  
   166  			// syn ack for non aporeto traffic can be let through
   167  			return conn, nil
   168  		}
   169  	default:
   170  		conn, err = d.appRetrieveState(p)
   171  		if err == errRstPacket {
   172  			return nil, nil
   173  		}
   174  
   175  		if err != nil {
   176  			debugLogs("Packet rejected")
   177  			return conn, err
   178  		}
   179  	}
   180  
   181  	conn.Lock()
   182  	defer conn.Unlock()
   183  
   184  	if conn.GetState() == connection.TCPSynReceived && p.GetTCPFlags()&packet.TCPRstMask != 0 && !conn.PingEnabled() {
   185  		// Seen a RST packet. Remove cache entries related to this connection
   186  		p.TCPDataDetach(0)
   187  		d.cacheRemove(d.tcpServer, p.L4ReverseFlowHash())
   188  		return conn, nil
   189  	}
   190  
   191  	err = d.processApplicationTCPPacket(p, conn.Context, conn)
   192  	if err != nil {
   193  		debugLogs("Dropping packet")
   194  		return conn, err
   195  	}
   196  
   197  	return conn, nil
   198  }
   199  
   200  // processApplicationTCPPacket processes a TCP packet and dispatches it to other methods based on the flags
   201  func (d *Datapath) processApplicationTCPPacket(tcpPacket *packet.Packet, context *pucontext.PUContext, conn *connection.TCPConnection) error {
   202  
   203  	// State machine based on the flags
   204  	switch tcpPacket.GetTCPFlags() & packet.TCPSynAckMask {
   205  	case packet.TCPSynMask: //Processing SYN packet from Application
   206  		return d.processApplicationSynPacket(tcpPacket, context, conn)
   207  
   208  	case packet.TCPAckMask:
   209  		if tcpPacket.GetTCPFlags()&packet.TCPFinMask != 0 {
   210  			conn.MarkForDeletion = true
   211  		}
   212  		return d.processApplicationAckPacket(tcpPacket, context, conn)
   213  
   214  	case packet.TCPSynAckMask:
   215  		return d.processApplicationSynAckPacket(tcpPacket, context, conn)
   216  	default:
   217  		return nil
   218  	}
   219  }
   220  
   221  // processApplicationSynPacket processes a single Syn Packet
   222  func (d *Datapath) processApplicationSynPacket(tcpPacket *packet.Packet, context *pucontext.PUContext, conn *connection.TCPConnection) error {
   223  	// Increment the counter.
   224  	conn.IncrementCounter()
   225  
   226  	if err := tcpPacket.CheckTCPAuthenticationOption(enforcerconstants.TCPAuthenticationOptionBaseLen); err == nil {
   227  		conn.Context.Counters().IncrementCounter(counters.ErrAppSynAuthOptionSet)
   228  	}
   229  
   230  	var tcpData []byte
   231  
   232  	conn.Secrets, conn.Auth.LocalDatapathPrivateKey, tcpData = context.GetSynToken(nil, conn.Auth.Nonce, nil)
   233  
   234  	buffer := append(tcpPacket.GetBuffer(0), []byte{packet.TCPAuthenticationOption, enforcerconstants.TCPAuthenticationOptionBaseLen, 0, 0}...)
   235  	buffer = append(buffer, tcpData...)
   236  	// Attach the tags to the packet and accept the packet
   237  	if err := tcpPacket.UpdatePacketBuffer(buffer, enforcerconstants.TCPAuthenticationOptionBaseLen); err != nil {
   238  		return err
   239  	}
   240  
   241  	// Set the state indicating that we send out a Syn packet
   242  	conn.SetState(connection.TCPSynSend)
   243  	d.cachePut(d.tcpClient, tcpPacket.L4FlowHash(), conn)
   244  
   245  	// Attach the tags to the packet and accept the packet
   246  	return nil
   247  }
   248  
   249  // processApplicationSynAckPacket processes an application SynAck packet
   250  func (d *Datapath) processApplicationSynAckPacket(tcpPacket *packet.Packet, _ *pucontext.PUContext, conn *connection.TCPConnection) error {
   251  	// if the traffic belongs to the same pu, let it go
   252  	if conn.GetState() == connection.TCPData && conn.IsLoopbackConnection() {
   253  		return nil
   254  	}
   255  
   256  	// If we are already in the connection.TCPData, it means that this is an external flow
   257  	// At this point we can release the flow to the kernel by updating conntrack
   258  	// We can also clean up the state since we are not going to see any more
   259  	// packets from this connection.
   260  	if conn.GetState() == connection.TCPData {
   261  		// remove from our tcp server cache
   262  		d.cacheRemove(d.tcpServer, tcpPacket.L4ReverseFlowHash())
   263  
   264  		if err := d.ignoreFlow(tcpPacket); err != nil {
   265  			zap.L().Error("Failed to ignore flow", zap.Error(err))
   266  		}
   267  		tcpPacket.SetConnmark = true
   268  		return nil
   269  	}
   270  
   271  	if err := tcpPacket.CheckTCPAuthenticationOption(enforcerconstants.TCPAuthenticationOptionBaseLen); err == nil {
   272  		conn.Context.Counters().IncrementCounter(counters.ErrAppSynAckAuthOptionSet)
   273  	}
   274  
   275  	buffer := append(tcpPacket.GetBuffer(0), []byte{packet.TCPAuthenticationOption, enforcerconstants.TCPAuthenticationOptionBaseLen, 0, 0}...)
   276  	buffer = append(buffer, conn.Auth.SynAckToken...)
   277  	if err := tcpPacket.UpdatePacketBuffer(buffer, enforcerconstants.TCPAuthenticationOptionBaseLen); err != nil {
   278  		return err
   279  	}
   280  
   281  	conn.SetState(connection.TCPSynAckSend)
   282  	return nil
   283  }
   284  
   285  // processApplicationAckPacket processes an application ack packet
   286  func (d *Datapath) processApplicationAckPacket(tcpPacket *packet.Packet, context *pucontext.PUContext, conn *connection.TCPConnection) error {
   287  	// Only process the first Ack of a connection. This means that we have received
   288  	// as SynAck packet and we can now process the ACK.
   289  	if conn.GetState() == connection.TCPSynAckReceived {
   290  
   291  		// Special case. We are handling an AP packet with data, but the ACK has been lost
   292  		// somewhere. In this case, we drop the payload and send our authorization data.
   293  		// The TCP stack will try again.
   294  		if !tcpPacket.IsEmptyTCPPayload() {
   295  			tcpPacket.TCPDataDetach(0)
   296  		}
   297  
   298  		buffer := append(tcpPacket.GetBuffer(0), []byte{packet.TCPAuthenticationOption, enforcerconstants.TCPAuthenticationOptionBaseLen, 0, 0}...)
   299  		buffer = append(buffer, conn.Auth.AckToken...)
   300  		if err := tcpPacket.UpdatePacketBuffer(buffer, enforcerconstants.TCPAuthenticationOptionBaseLen); err != nil {
   301  			return err
   302  		}
   303  
   304  		conn.SetState(connection.TCPAckSend)
   305  
   306  		return nil
   307  	}
   308  
   309  	// If we are already in the connection.TCPData connection just forward the packet
   310  	if conn.GetState() == connection.TCPData {
   311  		return nil
   312  	}
   313  
   314  	if conn.GetState() == connection.UnknownState {
   315  		// Check if the destination is in the external services approved cache
   316  		// and if yes, allow the packet to go and release the flow.
   317  		_, policy, perr := context.ApplicationACLPolicyFromAddr(tcpPacket.DestinationAddress(), tcpPacket.DestPort(), tcpPacket.IPProto())
   318  
   319  		if perr != nil {
   320  			conn.Context.Counters().CounterError(counters.ErrAckInUnknownState, nil) //nolint
   321  			zap.L().Debug("converting to rst app",
   322  				zap.String("SourceIP", tcpPacket.SourceAddress().String()),
   323  				zap.String("DestinationIP", tcpPacket.DestinationAddress().String()),
   324  				zap.Int("SourcePort", int(tcpPacket.SourcePort())),
   325  				zap.Int("DestinationPort", int(tcpPacket.DestPort())),
   326  				zap.String("Flags", packet.TCPFlagsToStr(tcpPacket.GetTCPFlags())),
   327  			)
   328  			tcpPacket.ConvertToRst()
   329  			tcpPacket.SetConnmark = true
   330  			return nil
   331  		}
   332  
   333  		if policy.Action.Rejected() {
   334  			return conn.Context.Counters().CounterError(counters.ErrRejectPacket, fmt.Errorf("Rejected due to policy %s", policy.PolicyID))
   335  		}
   336  		if err := d.ignoreFlow(tcpPacket); err != nil {
   337  			zap.L().Error("Failed to ignore flow", zap.Error(err))
   338  		}
   339  		tcpPacket.SetConnmark = true
   340  		return nil
   341  	}
   342  
   343  	// Here we capture the first data packet after an ACK packet by modyfing the
   344  	// state. We will not release the caches though to deal with re-transmissions.
   345  	// We will let the caches expire.
   346  	if conn.GetState() == connection.TCPAckSend {
   347  		if tcpPacket.SourceAddress().String() != tcpPacket.DestinationAddress().String() &&
   348  			!(tcpPacket.SourceAddress().IsLoopback() && tcpPacket.DestinationAddress().IsLoopback()) {
   349  
   350  			if err := d.ignoreFlow(tcpPacket); err != nil {
   351  				zap.L().Error("Failed to ignore flow", zap.Error(err))
   352  			}
   353  
   354  			conn.ResetTimer(waitBeforeRemovingConn)
   355  			tcpPacket.SetConnmark = true
   356  			counters.IncrementCounter(counters.ErrConnectionsProcessed)
   357  		}
   358  		conn.SetState(connection.TCPData)
   359  		return nil
   360  	}
   361  
   362  	return fmt.Errorf("received application ack packet in the wrong state: %d", conn.GetState())
   363  }
   364  
   365  // processNetworkTCPPacket processes a network TCP packet and dispatches it to different methods based on the flags
   366  func (d *Datapath) processNetworkTCPPacket(tcpPacket *packet.Packet, context *pucontext.PUContext, conn *connection.TCPConnection) (func(), error) {
   367  
   368  	// Update connection state in the internal state machine tracker
   369  	switch tcpPacket.GetTCPFlags() & packet.TCPSynAckMask {
   370  
   371  	case packet.TCPSynMask:
   372  		return d.processNetworkSynPacket(context, conn, tcpPacket)
   373  
   374  	case packet.TCPAckMask:
   375  		if tcpPacket.GetTCPFlags()&packet.TCPFinMask == packet.TCPFinMask {
   376  			conn.MarkForDeletion = true
   377  		}
   378  		return nil, d.processNetworkAckPacket(context, conn, tcpPacket)
   379  	case packet.TCPSynAckMask:
   380  		return d.processNetworkSynAckPacket(context, conn, tcpPacket)
   381  
   382  	default: // Ignore any other packet
   383  		return nil, nil
   384  	}
   385  }
   386  
   387  func (d *Datapath) clientIdentityAllowed(context *pucontext.PUContext, token []byte, tcpPacket *packet.Packet, conn *connection.TCPConnection, networkReport *policy.FlowPolicy) error {
   388  
   389  	claims := &conn.Auth.ConnectionClaims
   390  	secretKey, claimsHeader, controller, remoteNonce, remoteContextID, proto314, err := d.tokenAccessor.ParsePacketToken(conn.Auth.LocalDatapathPrivateKey, token, conn.Secrets, claims, false)
   391  
   392  	if err != nil {
   393  		zap.L().Error("Syn token Parse Error", zap.String("flow", tcpPacket.L4FlowHash()), zap.Error(err))
   394  		d.reportRejectedFlow(tcpPacket, conn, collector.DefaultEndPoint, context.ManagementID(), context, collector.InvalidToken, nil, nil, false)
   395  		return conn.Context.Counters().CounterError(netSynCounterFromError(err), err)
   396  	}
   397  
   398  	conn.Auth.SecretKey = secretKey
   399  	conn.Auth.RemoteNonce = remoteNonce
   400  	conn.Auth.RemoteContextID = remoteContextID
   401  	conn.Auth.Proto314 = proto314
   402  
   403  	if controller != nil &&
   404  		((!controller.SameController) ||
   405  			(claimsHeader != nil && claimsHeader.Ping())) {
   406  		conn.SourceController = controller.Controller
   407  	}
   408  
   409  	txLabel, ok := claims.T.Get(enforcerconstants.TransmitterLabel)
   410  	if !ok {
   411  		d.reportRejectedFlow(tcpPacket, conn, txLabel, context.ManagementID(), context, collector.InvalidFormat, nil, nil, false)
   412  		return conn.Context.Counters().CounterError(counters.ErrSynDroppedTCPOption, fmt.Errorf("ErrSynDroppedTCPOption"))
   413  	}
   414  
   415  	// Add the port as a label with an @ prefix. These labels are invalid otherwise
   416  	// If all policies are restricted by port numbers this will allow port-specific policies
   417  	tags := claims.T.Copy()
   418  	tags.AppendKeyValue(constants.PortNumberLabelString, fmt.Sprintf("%s/%s", constants.TCPProtoString, strconv.Itoa(int(tcpPacket.DestPort()))))
   419  
   420  	// Add the controller to the claims
   421  	if controller != nil && len(controller.Controller) > 0 {
   422  		tags.AppendKeyValue(constants.ControllerLabelString, controller.Controller)
   423  	}
   424  
   425  	report, pkt := context.SearchRcvRules(tags)
   426  
   427  	// If we have an ObserveContinue Rejected ACL, then report this as the observed flow.
   428  	if networkReport != nil && networkReport.Action.Rejected() && networkReport.ObserveAction.ObserveContinue() {
   429  		report = networkReport
   430  	}
   431  
   432  	conn.ReportFlowPolicy = report
   433  	conn.PacketFlowPolicy = pkt
   434  
   435  	if claimsHeader != nil && claimsHeader.Ping() && claims.P != nil {
   436  		err := d.processPingNetSynPacket(context, conn, tcpPacket, len(token), pkt, claims)
   437  		if err != nil && err != errDropPingNetSyn {
   438  			zap.L().Error("unable to process ping network syn", zap.Error(err))
   439  		}
   440  		return err
   441  	}
   442  
   443  	allow := false
   444  	if txLabel == context.ManagementID() {
   445  		zap.L().Debug("Traffic to the same pu", zap.String("flow", tcpPacket.L4FlowHash()))
   446  		conn.SetLoopbackConnection(true)
   447  		allow = true
   448  	}
   449  
   450  	if !pkt.Action.Rejected() || allow {
   451  		return nil
   452  	}
   453  
   454  	// TODO: Support ipv6
   455  	if tcpPacket.IPversion() == packet.V4 {
   456  		go func() {
   457  			if err := respondWithRstPacket(tcpPacket, rstIdentity); err != nil {
   458  				zap.L().Warn("unable to send rst packet", zap.Error(err))
   459  			}
   460  		}()
   461  	}
   462  
   463  	d.reportRejectedFlow(tcpPacket, conn, txLabel, context.ManagementID(), context, collector.PolicyDrop, report, pkt, false)
   464  	return conn.Context.Counters().CounterError(counters.ErrSynRejectPacket, fmt.Errorf("PolicyDrop %s", pkt.PolicyID))
   465  }
   466  
   467  // processNetworkSynPacket processes a syn packet arriving from the network
   468  func (d *Datapath) processNetworkSynPacket(context *pucontext.PUContext, conn *connection.TCPConnection, tcpPacket *packet.Packet) (func(), error) {
   469  	var err error
   470  	conn.IncrementCounter()
   471  
   472  	createSynAckToken := func() {
   473  		var pingPayload *policy.PingPayload
   474  		claimsHeader := claimsheader.NewClaimsHeader()
   475  
   476  		// This means we got syn with ping header set and passthrough enabled.
   477  		// The application responds with synack.
   478  		if conn.PingEnabled() {
   479  			pingPayload = &policy.PingPayload{}
   480  			conn.PingConfig.SetApplicationListening(true)
   481  			pingPayload.PingID = conn.PingConfig.PingID()
   482  			pingPayload.IterationID = conn.PingConfig.IterationID()
   483  			pingPayload.ApplicationListening = true
   484  			pingPayload.NamespaceHash = context.ManagementNamespaceHash()
   485  			claimsHeader.SetPing(true)
   486  		}
   487  
   488  		claims := &tokens.ConnectionClaims{
   489  			CT:       context.CompressedTags(),
   490  			LCL:      conn.Auth.Nonce[:],
   491  			RMT:      conn.Auth.RemoteNonce,
   492  			DEKV1:    conn.Auth.LocalDatapathPublicKeyV1,
   493  			SDEKV1:   conn.Auth.LocalDatapathPublicKeySignV1,
   494  			DEKV2:    conn.Auth.LocalDatapathPublicKeyV2,
   495  			SDEKV2:   conn.Auth.LocalDatapathPublicKeySignV2,
   496  			ID:       context.ManagementID(),
   497  			RemoteID: conn.Auth.RemoteContextID,
   498  			P:        pingPayload,
   499  		}
   500  
   501  		if conn.Auth.SynAckToken, err = d.tokenAccessor.CreateSynAckPacketToken(conn.Auth.Proto314, claims, conn.EncodedBuf[:], conn.Auth.Nonce[:], claimsHeader, conn.Secrets, conn.Auth.SecretKey); err != nil {
   502  			zap.L().Error("Syn/Ack token create failed", zap.String("flow", tcpPacket.L4FlowHash()), zap.Error(err))
   503  			conn.Context.Counters().CounterError(appSynCounterFromError(err), err) //nolint
   504  		}
   505  	}
   506  
   507  	allowPkt := func() {
   508  		tcpPacket.TCPDataDetach(enforcerconstants.TCPAuthenticationOptionBaseLen) //nolint
   509  		conn.SetState(connection.TCPSynReceived)
   510  		d.cachePut(d.tcpServer, tcpPacket.L4FlowHash(), conn)
   511  	}
   512  
   513  	// We should only be here if we have identity
   514  	if err = tcpPacket.CheckTCPAuthenticationOption(enforcerconstants.TCPAuthenticationOptionBaseLen); err != nil || (err == nil && tcpPacket.IsEmptyTCPPayload()) {
   515  		// This is not a normal case and should never happen because Linux/Windows rules are checking for this before sending the packet to NFQ.
   516  		if err == nil {
   517  			err = fmt.Errorf("identity payload empty: incoming connection dropped")
   518  		} else {
   519  			err = fmt.Errorf("invalid identity: incoming connection dropped: %s", err)
   520  		}
   521  		d.reportRejectedFlow(tcpPacket, conn, collector.DefaultEndPoint, context.ManagementID(), context, collector.MissingToken, nil, nil, false)
   522  		return nil, context.Counters().CounterError(counters.ErrSynMissingTCPOption, err)
   523  	}
   524  
   525  	rejected := false
   526  	networkReport, pkt, perr := context.NetworkACLPolicy(tcpPacket)
   527  	if perr == nil {
   528  		rejected = pkt.Action.Rejected()
   529  		if rejected {
   530  			perr = fmt.Errorf("rejected by ACL policy %s", pkt.PolicyID)
   531  		}
   532  	} else {
   533  		// We got an error, but ensure it isn't the catch all policy
   534  		if !(pkt != nil && pkt.Action.Rejected() && pkt.PolicyID == "default") {
   535  			rejected = true
   536  		}
   537  	}
   538  
   539  	if rejected {
   540  		d.reportExternalServiceFlow(context, networkReport, pkt, false, tcpPacket)
   541  		return nil, context.Counters().CounterError(counters.ErrSynFromExtNetReject, fmt.Errorf("packet had identity: incoming connection dropped: %s", perr))
   542  	}
   543  
   544  	token := tcpPacket.ReadTCPData()
   545  
   546  	if err = d.clientIdentityAllowed(context, token, tcpPacket, conn, networkReport); err == nil {
   547  		processAfterVerdict := func() {
   548  			createSynAckToken()
   549  		}
   550  
   551  		allowPkt()
   552  		return processAfterVerdict, nil
   553  	}
   554  
   555  	return nil, err
   556  }
   557  
   558  // policyPair stores both reporting and actual action taken on packet.
   559  type policyPair struct {
   560  	report *policy.FlowPolicy
   561  	packet *policy.FlowPolicy
   562  }
   563  
   564  // processNetworkSynAckPacket processes a SynAck packet arriving from the network
   565  func (d *Datapath) processNetworkSynAckPacket(context *pucontext.PUContext, conn *connection.TCPConnection, tcpPacket *packet.Packet) (func(), error) {
   566  	var err error
   567  
   568  	allowPkt := func() {
   569  		// Remove any of our data
   570  		conn.SetState(connection.TCPSynAckReceived)
   571  		tcpPacket.TCPDataDetach(enforcerconstants.TCPAuthenticationOptionBaseLen) //nolint
   572  	}
   573  
   574  	createAckToken := func() {
   575  		claims := &tokens.ConnectionClaims{
   576  			ID:       context.ManagementID(),
   577  			RMT:      conn.Auth.RemoteNonce,
   578  			RemoteID: conn.Auth.RemoteContextID,
   579  		}
   580  
   581  		// Create a new token that includes the source and destinatio nonce
   582  		// These are both challenges signed by the secret key and random for every
   583  		// connection minimizing the chances of a replay attack
   584  		if conn.Auth.AckToken, err = d.tokenAccessor.CreateAckPacketToken(conn.Auth.Proto314, conn.Auth.SecretKey, claims, conn.EncodedBuf[:]); err != nil {
   585  			zap.L().Error("Ack token create failed", zap.String("flow", tcpPacket.L4FlowHash()), zap.Error(err))
   586  			conn.Context.Counters().CounterError(appAckCounterFromError(err), err) //nolint
   587  		}
   588  	}
   589  
   590  	// Packets with no authorization are processed as external services based on the ACLS
   591  	if err = tcpPacket.CheckTCPAuthenticationOption(enforcerconstants.TCPAuthenticationOptionBaseLen); err != nil || (err == nil && tcpPacket.IsEmptyTCPPayload()) {
   592  
   593  		if _, err := d.puFromContextID.Get(conn.Context.ID()); err != nil {
   594  			// PU has been deleted. Ignore these packets
   595  			return nil, conn.Context.Counters().CounterError(counters.ErrInvalidSynAck, fmt.Errorf("Pu with ID delete %s", conn.Context.ID()))
   596  		}
   597  
   598  		flowHash := tcpPacket.SourceAddress().String() + ":" + strconv.Itoa(int(tcpPacket.SourcePort()))
   599  		if plci, plerr := context.RetrieveCachedExternalFlowPolicy(flowHash); plerr == nil {
   600  			plc := plci.(*policyPair)
   601  			d.releaseExternalFlow(context, plc.report, plc.packet, tcpPacket)
   602  			conn.Context.Counters().IncrementCounter(counters.ErrSynAckFromExtNetAccept)
   603  			return nil, nil
   604  		}
   605  
   606  		// Never seen this IP before, let's parse them.
   607  		report, pkt, perr := context.ApplicationACLPolicyFromAddr(tcpPacket.SourceAddress(), tcpPacket.SourcePort(), tcpPacket.IPProto())
   608  
   609  		// Ping packet from an external network.
   610  		if conn.PingEnabled() {
   611  			err := d.processPingNetSynAckPacket(context, conn, tcpPacket, 0, pkt, nil, true)
   612  			if err != nil && err != errDropPingNetSynAck {
   613  				zap.L().Error("unable to process ping network synack (externalnetwork)", zap.Error(err))
   614  			}
   615  			return nil, err
   616  		}
   617  
   618  		if perr != nil || pkt.Action.Rejected() {
   619  			d.reportReverseExternalServiceFlow(context, report, pkt, true, tcpPacket)
   620  			return nil, conn.Context.Counters().CounterError(counters.ErrSynAckFromExtNetReject, fmt.Errorf("ErrSynAckFromExtNetReject"))
   621  		}
   622  
   623  		// Added to the cache if we can accept it
   624  		context.CacheExternalFlowPolicy(
   625  			tcpPacket,
   626  			&policyPair{
   627  				report: report,
   628  				packet: pkt,
   629  			},
   630  		)
   631  
   632  		// Set the state to Data so the other state machines ignore subsequent packets
   633  		conn.SetState(connection.TCPData)
   634  		d.releaseExternalFlow(context, report, pkt, tcpPacket)
   635  		conn.Context.Counters().IncrementCounter(counters.ErrSynAckFromExtNetAccept)
   636  
   637  		return nil, nil
   638  	}
   639  
   640  	// This is a corner condition. We are receiving a SynAck packet and we are in
   641  	// a state that indicates that we have already processed one. This means that
   642  	// our ack packet was lost. We need to revert conntrack in this case and get
   643  	// back into the picture.
   644  	if conn.GetState() != connection.TCPSynSend {
   645  		// Revert the connmarks - dealing with retransmissions
   646  		if cerr := d.conntrack.UpdateApplicationFlowMark(
   647  			tcpPacket.DestinationAddress(),
   648  			tcpPacket.SourceAddress(),
   649  			tcpPacket.IPProto(),
   650  			tcpPacket.DestPort(),
   651  			tcpPacket.SourcePort(),
   652  			uint32(1), // We cannot put it back to zero. We need something other value.
   653  		); cerr != nil {
   654  			zap.L().Debug("Failed to update conntrack table for flow after synack packet",
   655  				zap.String("app-conn", tcpPacket.L4ReverseFlowHash()),
   656  				zap.String("state", fmt.Sprintf("%d", conn.GetState())),
   657  				zap.Error(err),
   658  			)
   659  		}
   660  
   661  		conn.SetState(connection.TCPSynAckReceived)
   662  	}
   663  
   664  	if !d.mutualAuthorization {
   665  		allowPkt()
   666  		return nil, nil
   667  	}
   668  
   669  	token := tcpPacket.ReadTCPData()
   670  	if err = d.serverIdentityAllowed(context, token, tcpPacket, conn); err == nil {
   671  		processAfterVerdict := func() {
   672  			createAckToken()
   673  		}
   674  		allowPkt()
   675  		return processAfterVerdict, nil
   676  	}
   677  
   678  	return nil, err
   679  }
   680  
   681  func (d *Datapath) serverIdentityAllowed(context *pucontext.PUContext, token []byte, tcpPacket *packet.Packet, conn *connection.TCPConnection) error {
   682  
   683  	claims := &conn.Auth.ConnectionClaims
   684  	secretKey, claimsHeader, controller, remoteNonce, remoteContextID, proto314, err := d.tokenAccessor.ParsePacketToken(conn.Auth.LocalDatapathPrivateKey, token, conn.Secrets, claims, true)
   685  
   686  	if err != nil {
   687  		zap.L().Error("Syn/Ack token parse error", zap.String("flow", tcpPacket.L4FlowHash()), zap.Error(err))
   688  		d.reportRejectedFlow(tcpPacket, conn, collector.DefaultEndPoint, context.ManagementID(), context, collector.InvalidToken, nil, nil, true)
   689  		return context.Counters().CounterError(netSynAckCounterFromError(err), err)
   690  	}
   691  
   692  	conn.Auth.SecretKey = secretKey
   693  	conn.Auth.RemoteNonce = remoteNonce
   694  	conn.Auth.RemoteContextID = remoteContextID
   695  	conn.Auth.Proto314 = proto314
   696  
   697  	if controller != nil && ((conn.PingEnabled()) || (!controller.SameController)) {
   698  		conn.DestinationController = controller.Controller
   699  	}
   700  
   701  	// Add the port as a label with an @ prefix. These labels are invalid otherwise
   702  	// If all policies are restricted by port numbers this will allow port-specific policies
   703  	tags := claims.T.Copy()
   704  	tags.AppendKeyValue(constants.PortNumberLabelString, constants.TCPProtoString+"/"+strconv.Itoa(int(tcpPacket.SourcePort())))
   705  
   706  	// Add the controller to the claims
   707  	if controller != nil && len(controller.Controller) > 0 {
   708  		tags.AppendKeyValue(constants.ControllerLabelString, controller.Controller)
   709  	}
   710  
   711  	report, pkt := context.SearchTxtRules(tags, !d.mutualAuthorization)
   712  
   713  	// Ping packet from remote enforcer.
   714  	if claimsHeader != nil {
   715  		if claimsHeader.Ping() && claims.P != nil {
   716  			payloadSize := len(token)
   717  			err := d.processPingNetSynAckPacket(context, conn, tcpPacket, payloadSize, pkt, claims, false)
   718  			if err != nil && err != errDropPingNetSynAck {
   719  				zap.L().Error("unable to process ping network synack", zap.Error(err))
   720  			}
   721  			return err
   722  		}
   723  	}
   724  
   725  	// Report and release traffic belonging to the same pu
   726  	if conn.Auth.RemoteContextID == context.ManagementID() {
   727  		conn.SetState(connection.TCPData)
   728  		conn.SetLoopbackConnection(true)
   729  		d.reportAcceptedFlow(tcpPacket, conn, conn.Auth.RemoteContextID, context.ManagementID(), context, nil, nil, true)
   730  		d.releaseUnmonitoredFlow(tcpPacket)
   731  		return nil
   732  	}
   733  
   734  	if pkt.Action.Rejected() {
   735  		d.reportRejectedFlow(tcpPacket, conn, conn.Auth.RemoteContextID, context.ManagementID(), context, collector.PolicyDrop, report, pkt, true)
   736  		return context.Counters().CounterError(counters.ErrSynAckRejected, fmt.Errorf("ErrSynAckRejected"))
   737  	}
   738  
   739  	return nil
   740  }
   741  
   742  // processNetworkAckPacket processes an Ack packet arriving from the network
   743  func (d *Datapath) processNetworkAckPacket(context *pucontext.PUContext, conn *connection.TCPConnection, tcpPacket *packet.Packet) error {
   744  
   745  	var err error
   746  
   747  	if conn.GetState() == connection.TCPData || conn.GetState() == connection.TCPAckSend {
   748  
   749  		// This rule is required as network packets are being duplicated by the middle box in google. Our ack packets contain payload and that will be sent to the tcp stack,
   750  		// if we don't drop them here.
   751  		if err := tcpPacket.CheckTCPAuthenticationOption(enforcerconstants.TCPAuthenticationOptionBaseLen); err == nil {
   752  			return conn.Context.Counters().CounterError(counters.ErrDuplicateAckDrop, fmt.Errorf("ErrDuplicateAckDrop"))
   753  		}
   754  
   755  		conn.ResetTimer(waitBeforeRemovingConn)
   756  		tcpPacket.SetConnmark = true
   757  		return nil
   758  	}
   759  
   760  	if conn.IsLoopbackConnection() {
   761  		conn.SetState(connection.TCPData)
   762  		d.releaseUnmonitoredFlow(tcpPacket)
   763  		return nil
   764  	}
   765  
   766  	// Validate that the source/destination nonse matches. The signature has validated both directions
   767  	if conn.GetState() == connection.TCPSynAckSend || conn.GetState() == connection.TCPSynReceived {
   768  
   769  		if err := tcpPacket.CheckTCPAuthenticationOption(enforcerconstants.TCPAuthenticationOptionBaseLen); err != nil {
   770  			return conn.Context.Counters().CounterError(counters.ErrAckTCPNoTCPAuthOption, fmt.Errorf("ErrAckTCPNoTCPAuthOption"))
   771  		}
   772  
   773  		if err = d.tokenAccessor.ParseAckToken(conn.Auth.Proto314, conn.Auth.SecretKey, conn.Auth.Nonce[:], tcpPacket.ReadTCPData(), &conn.Auth.ConnectionClaims); err != nil {
   774  			zap.L().Error("Ack Packet dropped because signature validation failed", zap.String("flow", tcpPacket.L4FlowHash()), zap.Error(err))
   775  			d.reportRejectedFlow(tcpPacket, conn, collector.DefaultEndPoint, context.ManagementID(), context, collector.InvalidToken, nil, nil, false)
   776  			return conn.Context.Counters().CounterError(netAckCounterFromError(err), err)
   777  		}
   778  
   779  		tcpPacket.TCPDataDetach(enforcerconstants.TCPAuthenticationOptionBaseLen)
   780  
   781  		if conn.PacketFlowPolicy != nil && conn.PacketFlowPolicy.Action.Rejected() {
   782  			if !conn.PacketFlowPolicy.ObserveAction.Observed() {
   783  				zap.L().Error("Flow rejected but not observed", zap.String("conn", context.ManagementID()))
   784  			}
   785  			// Flow has been allowed because we are observing a deny rule's impact on the system. Packets are forwarded, reported as dropped + observed.
   786  			d.reportRejectedFlow(tcpPacket, conn, conn.Auth.RemoteContextID, context.ManagementID(), context, collector.PolicyDrop, conn.ReportFlowPolicy, conn.PacketFlowPolicy, false)
   787  		} else {
   788  			// We accept the packet as a new flow
   789  			d.reportAcceptedFlow(tcpPacket, conn, conn.Auth.RemoteContextID, context.ManagementID(), context, conn.ReportFlowPolicy, conn.PacketFlowPolicy, false)
   790  		}
   791  
   792  		conn.SetState(connection.TCPData)
   793  
   794  		if err := d.ignoreFlow(tcpPacket); err != nil {
   795  			zap.L().Error("Failed to ignore flow", zap.Error(err))
   796  		}
   797  		conn.Context.Counters().IncrementCounter(counters.ErrConnectionsProcessed)
   798  		// Accept the packet
   799  		return nil
   800  	}
   801  
   802  	if conn.GetState() == connection.UnknownState {
   803  		// Check if the destination is in the external servicess approved cache
   804  		// and if yes, allow the packet to go and release the flow.
   805  		_, plcy, perr := context.NetworkACLPolicy(tcpPacket)
   806  
   807  		// Ignore FIN packets. Let them go through.
   808  		if tcpPacket.GetTCPFlags()&packet.TCPFinMask != 0 {
   809  			conn.Context.Counters().IncrementCounter(counters.ErrIgnoreFin)
   810  			return nil
   811  		}
   812  
   813  		if perr != nil {
   814  			conn.Context.Counters().CounterError(counters.ErrAckInUnknownState, nil) //nolint
   815  			zap.L().Debug("converting to rst network",
   816  				zap.String("SourceIP", tcpPacket.SourceAddress().String()),
   817  				zap.String("DestinationIP", tcpPacket.DestinationAddress().String()),
   818  				zap.Int("SourcePort", int(tcpPacket.SourcePort())),
   819  				zap.Int("DestinationPort", int(tcpPacket.DestPort())),
   820  				zap.String("Flags", packet.TCPFlagsToStr(tcpPacket.GetTCPFlags())),
   821  			)
   822  			tcpPacket.ConvertToRst()
   823  
   824  			tcpPacket.SetConnmark = true
   825  			return nil
   826  		}
   827  
   828  		if plcy.Action.Rejected() {
   829  			return conn.Context.Counters().CounterError(counters.ErrAckFromExtNetReject, fmt.Errorf("ErrAckFromExtNetReject"))
   830  		}
   831  
   832  		if err := d.ignoreFlow(tcpPacket); err != nil {
   833  			zap.L().Error("Failed to ignore flow", zap.Error(err))
   834  		}
   835  
   836  		tcpPacket.SetConnmark = true
   837  
   838  		conn.Context.Counters().IncrementCounter(counters.ErrAckFromExtNetAccept)
   839  		return nil
   840  	}
   841  
   842  	hash := tcpPacket.L4FlowHash()
   843  
   844  	// Everything else is dropped - ACK received in the Syn state without a SynAck
   845  	zap.L().Debug("Invalid state reached",
   846  		zap.String("state", fmt.Sprintf("%d", conn.GetState())),
   847  		zap.String("context", context.ManagementID()),
   848  		zap.String("net-conn", hash),
   849  	)
   850  
   851  	return conn.Context.Counters().CounterError(counters.ErrInvalidNetAckState, fmt.Errorf("ErrInvalidNetAckState"))
   852  }
   853  
   854  // appSynRetrieveState retrieves state for the the application Syn packet.
   855  // It creates a new connection by default
   856  func (d *Datapath) appSynRetrieveState(p *packet.Packet) (*connection.TCPConnection, error) {
   857  	var err error
   858  	var context *pucontext.PUContext
   859  
   860  	// If PU context doesn't exist for this syn, return error.
   861  	if context, err = d.contextFromIP(true, p.Mark, p.SourcePort(), packet.IPProtocolTCP); err != nil {
   862  		return nil, counters.CounterError(counters.ErrSynUnexpectedPacket, err)
   863  	}
   864  
   865  	// check if app syn has been seen?
   866  	if conn, exists := d.cacheGet(d.tcpClient, p.L4FlowHash()); exists {
   867  		if !conn.GetMarkForDeletion() && conn.GetInitialSequenceNumber() == p.TCPSequenceNumber() {
   868  			// return this connection only if we are not deleting this
   869  			// this is marked only when we see a FINACK for this l4flowhash
   870  			// this should not have happened for a connection while we are processing a appSyn for this connection
   871  			// The addorupdate for this cache will happen outside in processtcppacket
   872  			return conn, nil
   873  		} else { //nolint
   874  			//stale app syn. We remove from the cache
   875  			d.cacheRemove(d.tcpClient, p.L4FlowHash())
   876  		}
   877  	}
   878  	return connection.NewTCPConnection(context, p), nil
   879  }
   880  
   881  // appSynAckRetrieveState retrieves the state for application syn/ack packet.
   882  func (d *Datapath) appSynAckRetrieveState(p *packet.Packet) (*connection.TCPConnection, error) {
   883  	hash := p.L4ReverseFlowHash()
   884  
   885  	// We must have seen a network syn.
   886  	if conn, exists := d.cacheGet(d.tcpServer, hash); exists {
   887  		return conn, nil
   888  	}
   889  
   890  	return nil, counters.CounterError(counters.ErrNetSynNotSeen, errors.New("Network Syn not seen"))
   891  }
   892  
   893  // appRetrieveState retrieves the state for the rest of the application packets. It
   894  // returns an error if it cannot find the state
   895  func (d *Datapath) appRetrieveState(p *packet.Packet) (*connection.TCPConnection, error) {
   896  
   897  	// Is this ack generated from a PU, a tcp client.
   898  	if conn, exists := d.cacheGet(d.tcpClient, p.L4FlowHash()); exists {
   899  		return conn, nil
   900  	}
   901  
   902  	// is this ack generated from a PU, a tcp server.
   903  	if conn, exists := d.cacheGet(d.tcpServer, p.L4ReverseFlowHash()); exists {
   904  		return conn, nil
   905  	}
   906  
   907  	counters.CounterError(counters.ErrNoConnFound, nil) //nolint
   908  
   909  	zap.L().Debug("Application ACK Packet received with no state",
   910  		zap.String("flow", p.L4FlowHash()),
   911  		zap.String("Flags", packet.TCPFlagsToStr(p.GetTCPFlags())))
   912  
   913  	if p.GetTCPFlags()&packet.TCPSynAckMask == packet.TCPAckMask {
   914  		// Let's try if its an existing connection
   915  		context, err := d.contextFromIP(true, p.Mark, p.SourcePort(), packet.IPProtocolTCP)
   916  		if err != nil {
   917  			return nil, errors.New("No context in app processing")
   918  		}
   919  		conn := connection.NewTCPConnection(context, p)
   920  		conn.SetState(connection.UnknownState)
   921  		return conn, nil
   922  	}
   923  
   924  	if p.GetTCPFlags()&packet.TCPRstMask != 0 && p.GetTCPFlags()&packet.TCPAckMask == 0 {
   925  		return nil, errRstPacket
   926  	}
   927  
   928  	return nil, errNoConnection
   929  }
   930  
   931  // netSynRetrieveState retrieves the state for the Syn packets on the network.
   932  // Obviously if no state is found, it generates a new connection record.
   933  func (d *Datapath) netSynRetrieveState(p *packet.Packet) (*connection.TCPConnection, error) {
   934  
   935  	var conn *connection.TCPConnection
   936  	var context *pucontext.PUContext
   937  	var err error
   938  
   939  	if context, err = d.contextFromIP(false, p.Mark, p.DestPort(), packet.IPProtocolTCP); err != nil {
   940  		return nil, counters.CounterError(counters.ErrInvalidNetSynState, err)
   941  	}
   942  
   943  	if conn, exists := d.cacheGet(d.tcpServer, p.L4FlowHash()); exists {
   944  		if !conn.GetMarkForDeletion() && conn.GetInitialSequenceNumber() == p.TCPSequenceNumber() {
   945  			// Only if we havent seen FINACK on this connection
   946  			return conn, nil
   947  		} else { //nolint
   948  			// remove stale net syn entry
   949  			d.cacheRemove(d.tcpServer, p.L4FlowHash())
   950  		}
   951  	}
   952  
   953  	conn = connection.NewTCPConnection(context, p)
   954  
   955  	conn.Secrets, conn.Auth.LocalDatapathPrivateKey, conn.Auth.LocalDatapathPublicKeyV1, conn.Auth.LocalDatapathPublicKeySignV1, conn.Auth.LocalDatapathPublicKeyV2, conn.Auth.LocalDatapathPublicKeySignV2 = context.GetSecrets()
   956  	return conn, nil
   957  }
   958  
   959  // netSynAckRetrieveState retrieves the state for SynAck packets at the network
   960  // It relies on the source port cache for that
   961  func (d *Datapath) netSynAckRetrieveState(p *packet.Packet) (*connection.TCPConnection, error) {
   962  
   963  	// We must have seen App Syn
   964  	if conn, exists := d.cacheGet(d.tcpClient, p.L4ReverseFlowHash()); exists {
   965  		if conn.GetMarkForDeletion() {
   966  			return nil, errOutOfOrderSynAck
   967  		}
   968  		return conn, nil
   969  	}
   970  
   971  	return nil, counters.CounterError(counters.ErrNonPUTraffic, errNonPUTraffic)
   972  }
   973  
   974  // netRetrieveState retrieves the state of a network connection. Use the flow caches for that
   975  func (d *Datapath) netRetrieveState(p *packet.Packet) (*connection.TCPConnection, error) {
   976  	// Is the ack received by a tcp client
   977  	if conn, exists := d.cacheGet(d.tcpClient, p.L4ReverseFlowHash()); exists {
   978  		if p.GetTCPFlags()&packet.TCPRstMask != 0 && p.GetTCPFlags()&packet.TCPAckMask == 0 {
   979  			if !bytes.Equal(p.ReadTCPData(), rstIdentity) {
   980  				conn.SetReportReason("reset")
   981  			}
   982  			return conn, errRstPacket
   983  		}
   984  		return conn, nil
   985  	}
   986  
   987  	// Is the ack received by a tcp server
   988  	if conn, exists := d.cacheGet(d.tcpServer, p.L4FlowHash()); exists {
   989  		return conn, nil
   990  	}
   991  
   992  	if p.GetTCPFlags()&packet.TCPSynAckMask == packet.TCPAckMask {
   993  		// Let's try if its an existing connection
   994  		context, cerr := d.contextFromIP(false, p.Mark, p.DestPort(), packet.IPProtocolTCP)
   995  		if cerr != nil {
   996  			return nil, cerr
   997  		}
   998  		conn := connection.NewTCPConnection(context, p)
   999  		conn.SetState(connection.UnknownState)
  1000  		return conn, nil
  1001  	}
  1002  
  1003  	if p.GetTCPFlags()&packet.TCPRstMask != 0 && p.GetTCPFlags()&packet.TCPAckMask == 0 {
  1004  		return nil, errRstPacket
  1005  	}
  1006  
  1007  	return nil, errNoConnection
  1008  }
  1009  
  1010  // releaseExternalFlow releases the flow and updates the conntrack table
  1011  func (d *Datapath) releaseExternalFlow(context *pucontext.PUContext, report *policy.FlowPolicy, action *policy.FlowPolicy, tcpPacket *packet.Packet) {
  1012  
  1013  	d.cacheRemove(d.tcpClient, tcpPacket.L4ReverseFlowHash())
  1014  
  1015  	if err := d.ignoreFlow(tcpPacket); err != nil {
  1016  		zap.L().Error("Failed to ignore flow", zap.Error(err))
  1017  	}
  1018  
  1019  	tcpPacket.SetConnmark = true
  1020  	d.reportReverseExternalServiceFlow(context, report, action, true, tcpPacket)
  1021  }
  1022  
  1023  // releaseUnmonitoredFlow releases the flow and updates the conntrack table
  1024  func (d *Datapath) releaseUnmonitoredFlow(tcpPacket *packet.Packet) {
  1025  
  1026  	if err := d.ignoreFlow(tcpPacket); err != nil {
  1027  		zap.L().Error("Failed to ignore flow", zap.Error(err))
  1028  	}
  1029  
  1030  	tcpPacket.SetConnmark = true
  1031  }