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

     1  // +build linux
     2  
     3  package nfqdatapath
     4  
     5  import (
     6  	"context"
     7  	"errors"
     8  	"fmt"
     9  	"net"
    10  	"sync/atomic"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/ghedo/go.pkt/layers"
    15  	gpacket "github.com/ghedo/go.pkt/packet"
    16  	"github.com/ghedo/go.pkt/packet/ipv4"
    17  	"github.com/ghedo/go.pkt/packet/tcp"
    18  	"github.com/golang/mock/gomock"
    19  	"github.com/mitchellh/copystructure"
    20  	"github.com/stretchr/testify/require"
    21  	"go.aporeto.io/enforcerd/trireme-lib/collector"
    22  	"go.aporeto.io/enforcerd/trireme-lib/collector/mockcollector"
    23  	"go.aporeto.io/enforcerd/trireme-lib/common"
    24  	enforcerconstants "go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/constants"
    25  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/nfqdatapath/tokenaccessor"
    26  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/nfqdatapath/tokenaccessor/mocktokenaccessor"
    27  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/connection"
    28  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/packet"
    29  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/pucontext"
    30  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/tokens"
    31  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    32  	"go.aporeto.io/gaia"
    33  	"go.aporeto.io/underwater/core/tagutils"
    34  )
    35  
    36  var (
    37  	testPU1CtxID  = "pu1abc"
    38  	testPU1NS     = "/ns1"
    39  	testPU1NSHash = ""
    40  	testPU2CtxID  = "pu2abc"
    41  	testPU2NS     = "/ns2"
    42  	testPU2NSHash = ""
    43  	srcCtrl       = "srcctrl"
    44  	dstCtrl       = "dstctrl"
    45  
    46  	sip                 = net.ParseIP("192.168.100.1").To4()
    47  	dip                 = net.ParseIP("172.17.0.2").To4()
    48  	spt          uint16 = 2020
    49  	dpt          uint16 = 80
    50  	seqnum       uint32 = 123456
    51  	duration            = "20ms"
    52  	c                   = &fakeConn{}
    53  	appListening int32  = 0
    54  )
    55  
    56  func switchAppListening(enable bool) {
    57  
    58  	var state int32
    59  	if enable {
    60  		state = 1
    61  	}
    62  
    63  	atomic.StoreInt32(&appListening, state)
    64  }
    65  
    66  func init() {
    67  	if hash, err := tagutils.Hash(testPU1NS); err == nil {
    68  		testPU1NSHash = hash
    69  	}
    70  
    71  	if hash, err := tagutils.Hash(testPU2NS); err == nil {
    72  		testPU2NSHash = hash
    73  	}
    74  
    75  	srcip = func(_ net.IP) (net.IP, error) {
    76  		return sip, nil
    77  	}
    78  	dial = func(_, _ net.IP) (PingConn, error) {
    79  		return c, nil
    80  	}
    81  	bind = func(tcpConn *connection.TCPConnection) (uint16, error) {
    82  		tcpConn.PingConfig.SetSocketFd(8)
    83  		return spt, nil
    84  	}
    85  	close = func(tcpConn *connection.TCPConnection) error {
    86  		tcpConn.PingConfig.SetSocketClosed(true)
    87  		return nil
    88  	}
    89  	randUint32 = func() uint32 {
    90  		return seqnum
    91  	}
    92  	since = func(_ time.Time) time.Duration {
    93  		d, _ := time.ParseDuration(duration)
    94  		return d
    95  	}
    96  
    97  	isAppListening = func(port uint16) (bool, error) {
    98  		if atomic.LoadInt32(&appListening) == 1 {
    99  			return true, nil
   100  		}
   101  		return false, nil
   102  	}
   103  }
   104  
   105  func setupDatapathAndPUs(ctrl *gomock.Controller, collector collector.EventCollector, tokenAccessor tokenaccessor.TokenAccessor) (*Datapath, *fakeConn, error) {
   106  
   107  	dp := setupDatapath(ctrl, collector)
   108  	dp.tokenAccessor = tokenAccessor
   109  
   110  	pu1info := policy.NewPUInfo(testPU1CtxID, testPU1NS, common.ContainerPU)
   111  	pu1info.Policy = policy.NewPUPolicy(
   112  		testPU1CtxID,
   113  		testPU1NS,
   114  		policy.Police,
   115  		nil,
   116  		nil,
   117  		nil,
   118  		nil,
   119  		nil,
   120  		policy.NewTagStoreFromSlice([]string{"x=y"}),
   121  		nil,
   122  		nil,
   123  		nil,
   124  		0,
   125  		0,
   126  		nil,
   127  		nil,
   128  		nil,
   129  		policy.EnforcerMapping,
   130  		policy.Reject|policy.Log,
   131  		policy.Reject|policy.Log,
   132  	)
   133  
   134  	if err := dp.Enforce(context.Background(), testPU1CtxID, pu1info); err != nil {
   135  		return nil, nil, err
   136  	}
   137  
   138  	pu2info := policy.NewPUInfo(testPU2CtxID, testPU2NS, common.ContainerPU)
   139  	pu2info.Policy = policy.NewPUPolicy(
   140  		testPU2CtxID,
   141  		testPU2NS,
   142  		policy.Police,
   143  		nil,
   144  		nil,
   145  		nil,
   146  		nil,
   147  		nil,
   148  		policy.NewTagStoreFromSlice([]string{"a=b"}),
   149  		nil,
   150  		nil,
   151  		nil,
   152  		0,
   153  		0,
   154  		nil,
   155  		nil,
   156  		nil,
   157  		policy.EnforcerMapping,
   158  		policy.Reject|policy.Log,
   159  		policy.Reject|policy.Log,
   160  	)
   161  
   162  	if err := dp.Enforce(context.Background(), testPU2CtxID, pu2info); err != nil {
   163  		return nil, nil, err
   164  	}
   165  
   166  	return dp, c, nil
   167  }
   168  
   169  func wrapIP(d []byte, swap bool, changeSeqNum bool, flags tcp.Flags) ([]byte, error) {
   170  
   171  	ipPacket := ipv4.Make()
   172  	ipPacket.SrcAddr = sip
   173  	ipPacket.DstAddr = dip
   174  	if swap {
   175  		ipPacket.SrcAddr = dip
   176  		ipPacket.DstAddr = sip
   177  	}
   178  	ipPacket.Protocol = ipv4.TCP
   179  
   180  	p, err := layers.UnpackAll(d, gpacket.TCP)
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  
   185  	tcpPacket, ok := p.(*tcp.Packet)
   186  	if !ok {
   187  		return nil, errors.New("not a tcp packet")
   188  	}
   189  
   190  	if flags != 0 {
   191  		if flags != tcpPacket.Flags {
   192  			return nil, fmt.Errorf("Expected: %s, Actual: %s", flags.String(), tcpPacket.Flags.String())
   193  		}
   194  	}
   195  
   196  	if swap {
   197  		tcpPacket.SrcPort = dpt
   198  		tcpPacket.DstPort = spt
   199  	}
   200  
   201  	if changeSeqNum {
   202  		tcpPacket.Seq = 111111
   203  	}
   204  
   205  	// pack the layers together.
   206  	buf, err := layers.Pack(ipPacket, tcpPacket)
   207  	if err != nil {
   208  		return nil, err
   209  	}
   210  
   211  	return buf, nil
   212  }
   213  
   214  func Test_ValidPing(t *testing.T) {
   215  
   216  	ctrl := gomock.NewController(t)
   217  	defer ctrl.Finish()
   218  
   219  	mockCollector := mockcollector.NewMockEventCollector(ctrl)
   220  	mockTokenAccessor := mocktokenaccessor.NewMockTokenAccessor(ctrl)
   221  	mockTokenAccessor.EXPECT().Sign(gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil).AnyTimes()
   222  	mockTokenAccessor.EXPECT().CreateSynPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil)
   223  	dp, conn, err := setupDatapathAndPUs(ctrl, mockCollector, mockTokenAccessor)
   224  	require.Nil(t, err)
   225  	require.NotNil(t, dp)
   226  
   227  	item, err := dp.puFromContextID.Get(testPU1CtxID)
   228  	require.Nil(t, err)
   229  	require.NotNil(t, item)
   230  	puctx1 := item.(*pucontext.PUContext)
   231  
   232  	item, err = dp.puFromContextID.Get(testPU2CtxID)
   233  	require.Nil(t, err)
   234  	require.NotNil(t, item)
   235  	puctx2 := item.(*pucontext.PUContext)
   236  
   237  	pc := &policy.PingConfig{
   238  		ID:                "5e9e38ad39483e772044095e",
   239  		IP:                dip,
   240  		Port:              dpt,
   241  		Iterations:        1,
   242  		TargetTCPNetworks: true,
   243  		ExcludedNetworks:  false,
   244  	}
   245  
   246  	pingPayload := &policy.PingPayload{
   247  		PingID:               pc.ID,
   248  		IterationID:          0,
   249  		ApplicationListening: false,
   250  		NamespaceHash:        testPU1NSHash,
   251  	}
   252  
   253  	puctx1.UpdateApplicationACLs( // nolint: errcheck
   254  		policy.IPRuleList{
   255  			policy.IPRule{
   256  				Addresses: []string{"0.0.0.0/0"},
   257  				Ports:     []string{"1:65535"},
   258  				Protocols: []string{"6", "17"},
   259  				Policy: &policy.FlowPolicy{
   260  					Action:   policy.Accept,
   261  					PolicyID: "extnetidabc",
   262  				},
   263  			},
   264  		},
   265  	)
   266  
   267  	//	mockTokenAccessor.EXPECT().CreateSynPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return([]byte("token"), nil)
   268  
   269  	err = dp.Ping(context.Background(), testPU1CtxID, pc)
   270  	require.Nil(t, err)
   271  
   272  	// NetSyn
   273  	ipPacket, err := wrapIP(conn.data(), false, false, tcp.Syn)
   274  	require.Nil(t, err)
   275  
   276  	p, err := packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
   277  	require.Nil(t, err)
   278  	require.NotNil(t, p)
   279  	payloadSize := len(p.ReadTCPData())
   280  	tcpConn := connection.NewTCPConnection(puctx2, p)
   281  	tcpConn.SourceController = srcCtrl
   282  	pkt := &policy.FlowPolicy{Action: policy.Accept, PolicyID: "abc"}
   283  
   284  	ts := policy.NewTagStore()
   285  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU1CtxID)
   286  	claims := &tokens.ConnectionClaims{
   287  		P: pingPayload,
   288  		T: ts,
   289  	}
   290  
   291  	pr := &collector.PingReport{
   292  		PingID:               pc.ID,
   293  		IterationID:          0,
   294  		Type:                 gaia.PingProbeTypeRequest,
   295  		PUID:                 testPU2CtxID,
   296  		RemotePUID:           testPU1CtxID,
   297  		Namespace:            testPU2NS,
   298  		FourTuple:            "192.168.100.1:172.17.0.2:2020:80",
   299  		RTT:                  "",
   300  		Protocol:             6,
   301  		ServiceType:          "L3",
   302  		PayloadSize:          payloadSize,
   303  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
   304  		PolicyID:             "abc",
   305  		PolicyAction:         policy.Accept,
   306  		AgentVersion:         "0.0.0",
   307  		ApplicationListening: false,
   308  		RemoteEndpointType:   collector.EndPointTypePU,
   309  		SeqNum:               seqnum,
   310  		TargetTCPNetworks:    true,
   311  		ExcludedNetworks:     false,
   312  		Claims:               []string{"a=b"},
   313  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
   314  		RemoteNamespace:      testPU1NSHash,
   315  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
   316  		ACLPolicyID:          "",
   317  		ACLPolicyAction:      policy.ActionType(0),
   318  		RemoteController:     srcCtrl,
   319  		IsServer:             true,
   320  	}
   321  
   322  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
   323  	copiedData, err := copystructure.Copy(pingPayload)
   324  	synAckPayload := copiedData.(*policy.PingPayload)
   325  	synAckPayload.NamespaceHash = testPU2NSHash
   326  	require.Nil(t, err)
   327  	mockTokenAccessor.EXPECT().CreateSynAckPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return([]byte("token"), nil)
   328  
   329  	oldsynAckDelay := synAckDelay
   330  	synAckDelay = 1 * time.Second
   331  	defer func() {
   332  		synAckDelay = oldsynAckDelay
   333  	}()
   334  
   335  	err = dp.processPingNetSynPacket(puctx2, tcpConn, p, payloadSize, pkt, claims)
   336  	require.Equal(t, errDropPingNetSyn, err)
   337  
   338  	time.Sleep(2 * time.Second)
   339  
   340  	// NetSynAck
   341  	ipPacket, err = wrapIP(conn.data(), true, false, tcp.Syn|tcp.Ack)
   342  	require.Nil(t, err)
   343  
   344  	p, err = packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
   345  	require.Nil(t, err)
   346  	require.NotNil(t, p)
   347  
   348  	item1, exists := dp.tcpClient.Get(p.L4ReverseFlowHash())
   349  	if !exists {
   350  		t.Fail()
   351  	}
   352  
   353  	tcpConn = item1
   354  	tcpConn.DestinationController = dstCtrl
   355  
   356  	pkt = &policy.FlowPolicy{Action: policy.Accept, PolicyID: "abc"}
   357  
   358  	ts = policy.NewTagStore()
   359  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU2CtxID)
   360  	claims = &tokens.ConnectionClaims{
   361  		P: pingPayload,
   362  		T: ts,
   363  	}
   364  
   365  	pr = &collector.PingReport{
   366  		PingID:               pc.ID,
   367  		IterationID:          0,
   368  		Type:                 gaia.PingProbeTypeResponse,
   369  		PUID:                 testPU1CtxID,
   370  		RemotePUID:           testPU2CtxID,
   371  		Namespace:            testPU1NS,
   372  		FourTuple:            "172.17.0.2:192.168.100.1:80:2020",
   373  		RTT:                  duration,
   374  		Protocol:             6,
   375  		ServiceType:          "L3",
   376  		PayloadSize:          payloadSize,
   377  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
   378  		PolicyID:             "abc",
   379  		PolicyAction:         policy.Accept,
   380  		AgentVersion:         "0.0.0",
   381  		ApplicationListening: false,
   382  		RemoteEndpointType:   collector.EndPointTypePU,
   383  		SeqNum:               seqnum,
   384  		TargetTCPNetworks:    true,
   385  		ExcludedNetworks:     false,
   386  		Claims:               []string{"x=y"},
   387  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
   388  		RemoteNamespace:      testPU2NSHash,
   389  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
   390  		ACLPolicyID:          "extnetidabc",
   391  		ACLPolicyAction:      policy.Accept,
   392  		RemoteController:     dstCtrl,
   393  	}
   394  
   395  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
   396  
   397  	claims.P.NamespaceHash = testPU2NSHash
   398  	err = dp.processPingNetSynAckPacket(puctx1, tcpConn, p, payloadSize, pkt, claims, false)
   399  	require.Equal(t, errDropPingNetSynAck, err)
   400  }
   401  
   402  func Test_ValidPingAppListening(t *testing.T) {
   403  
   404  	ctrl := gomock.NewController(t)
   405  	defer func() {
   406  		switchAppListening(false)
   407  		ctrl.Finish()
   408  	}()
   409  
   410  	mockCollector := mockcollector.NewMockEventCollector(ctrl)
   411  	mockTokenAccessor := mocktokenaccessor.NewMockTokenAccessor(ctrl)
   412  
   413  	mockTokenAccessor.EXPECT().Sign(gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil).AnyTimes()
   414  	mockTokenAccessor.EXPECT().CreateSynPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil)
   415  
   416  	dp, conn, err := setupDatapathAndPUs(ctrl, mockCollector, mockTokenAccessor)
   417  	require.Nil(t, err)
   418  	require.NotNil(t, dp)
   419  
   420  	item, err := dp.puFromContextID.Get(testPU1CtxID)
   421  	require.Nil(t, err)
   422  	require.NotNil(t, item)
   423  	puctx1 := item.(*pucontext.PUContext)
   424  
   425  	item, err = dp.puFromContextID.Get(testPU2CtxID)
   426  	require.Nil(t, err)
   427  	require.NotNil(t, item)
   428  	puctx2 := item.(*pucontext.PUContext)
   429  
   430  	pc := &policy.PingConfig{
   431  		ID:                "5e9e38ad39483e772044095e",
   432  		IP:                dip,
   433  		Port:              dpt,
   434  		Iterations:        1,
   435  		TargetTCPNetworks: true,
   436  		ExcludedNetworks:  false,
   437  	}
   438  
   439  	pingPayload := &policy.PingPayload{
   440  		PingID:               pc.ID,
   441  		IterationID:          0,
   442  		ApplicationListening: false,
   443  		NamespaceHash:        testPU1NSHash,
   444  	}
   445  
   446  	puctx1.UpdateApplicationACLs( // nolint: errcheck
   447  		policy.IPRuleList{
   448  			policy.IPRule{
   449  				Addresses: []string{"0.0.0.0/0"},
   450  				Ports:     []string{"1:65535"},
   451  				Protocols: []string{"6", "17"},
   452  				Policy: &policy.FlowPolicy{
   453  					Action:   policy.Accept,
   454  					PolicyID: "extnetidabc",
   455  				},
   456  			},
   457  		},
   458  	)
   459  
   460  	err = dp.Ping(context.Background(), testPU1CtxID, pc)
   461  	require.Nil(t, err)
   462  
   463  	// NetSyn
   464  	ipPacket, err := wrapIP(conn.data(), false, false, tcp.Syn)
   465  	require.Nil(t, err)
   466  
   467  	p, err := packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
   468  	require.Nil(t, err)
   469  	require.NotNil(t, p)
   470  	payloadSize := len(p.ReadTCPData())
   471  	tcpConn := connection.NewTCPConnection(puctx2, p)
   472  	tcpConn.SourceController = srcCtrl
   473  	pkt := &policy.FlowPolicy{Action: policy.Accept, PolicyID: "abc"}
   474  
   475  	ts := policy.NewTagStore()
   476  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU1CtxID)
   477  	claims := &tokens.ConnectionClaims{
   478  		P: pingPayload,
   479  		T: ts,
   480  	}
   481  
   482  	pr := &collector.PingReport{
   483  		PingID:               pc.ID,
   484  		IterationID:          0,
   485  		Type:                 gaia.PingProbeTypeRequest,
   486  		PUID:                 testPU2CtxID,
   487  		RemotePUID:           testPU1CtxID,
   488  		Namespace:            testPU2NS,
   489  		FourTuple:            "192.168.100.1:172.17.0.2:2020:80",
   490  		RTT:                  "",
   491  		Protocol:             6,
   492  		ServiceType:          "L3",
   493  		PayloadSize:          payloadSize,
   494  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
   495  		PolicyID:             "abc",
   496  		PolicyAction:         policy.Accept,
   497  		AgentVersion:         "0.0.0",
   498  		ApplicationListening: false,
   499  		RemoteEndpointType:   collector.EndPointTypePU,
   500  		SeqNum:               seqnum,
   501  		TargetTCPNetworks:    true,
   502  		ExcludedNetworks:     false,
   503  		Claims:               []string{"a=b"},
   504  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
   505  		RemoteNamespace:      testPU1NSHash,
   506  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
   507  		ACLPolicyID:          "",
   508  		ACLPolicyAction:      policy.ActionType(0),
   509  		RemoteController:     srcCtrl,
   510  		IsServer:             true,
   511  	}
   512  
   513  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
   514  
   515  	oldsynAckDelay := synAckDelay
   516  	synAckDelay = 1 * time.Second
   517  	defer func() {
   518  		synAckDelay = oldsynAckDelay
   519  	}()
   520  
   521  	switchAppListening(true)
   522  	err = dp.processPingNetSynPacket(puctx2, tcpConn, p, payloadSize, pkt, claims)
   523  	require.Nil(t, err)
   524  
   525  	tcpConn.PingConfig.SetApplicationListening(true)
   526  
   527  	time.Sleep(2 * time.Second)
   528  
   529  	// NetSynAck
   530  	ipPacket, err = wrapIP(conn.data(), true, false, 0)
   531  	require.Nil(t, err)
   532  
   533  	p, err = packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
   534  	require.Nil(t, err)
   535  	require.NotNil(t, p)
   536  
   537  	item1, exists := dp.tcpClient.Get(p.L4ReverseFlowHash())
   538  	if !exists {
   539  		t.Fail()
   540  	}
   541  
   542  	tcpConn = item1
   543  	tcpConn.DestinationController = dstCtrl
   544  
   545  	pkt = &policy.FlowPolicy{Action: policy.Accept, PolicyID: "abc"}
   546  
   547  	ts = policy.NewTagStore()
   548  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU2CtxID)
   549  	claims = &tokens.ConnectionClaims{
   550  		P: pingPayload,
   551  		T: ts,
   552  	}
   553  
   554  	pr = &collector.PingReport{
   555  		PingID:               pc.ID,
   556  		IterationID:          0,
   557  		Type:                 gaia.PingProbeTypeResponse,
   558  		PUID:                 testPU1CtxID,
   559  		RemotePUID:           testPU2CtxID,
   560  		Namespace:            testPU1NS,
   561  		FourTuple:            "172.17.0.2:192.168.100.1:80:2020",
   562  		RTT:                  duration,
   563  		Protocol:             6,
   564  		ServiceType:          "L3",
   565  		PayloadSize:          payloadSize,
   566  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
   567  		PolicyID:             "abc",
   568  		PolicyAction:         policy.Accept,
   569  		AgentVersion:         "0.0.0",
   570  		ApplicationListening: true,
   571  		RemoteEndpointType:   collector.EndPointTypePU,
   572  		SeqNum:               seqnum,
   573  		TargetTCPNetworks:    true,
   574  		ExcludedNetworks:     false,
   575  		Claims:               []string{"x=y"},
   576  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
   577  		RemoteNamespace:      testPU2NSHash,
   578  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
   579  		ACLPolicyID:          "extnetidabc",
   580  		ACLPolicyAction:      policy.Accept,
   581  		RemoteController:     dstCtrl,
   582  	}
   583  
   584  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
   585  
   586  	claims.P.ApplicationListening = true
   587  	claims.P.NamespaceHash = testPU2NSHash
   588  	err = dp.processPingNetSynAckPacket(puctx1, tcpConn, p, payloadSize, pkt, claims, false)
   589  	require.Equal(t, errDropPingNetSynAck, err)
   590  }
   591  
   592  func Test_ValidPingAppListeningNoReply(t *testing.T) {
   593  
   594  	ctrl := gomock.NewController(t)
   595  	defer func() {
   596  		switchAppListening(false)
   597  		ctrl.Finish()
   598  	}()
   599  
   600  	mockCollector := mockcollector.NewMockEventCollector(ctrl)
   601  	mockTokenAccessor := mocktokenaccessor.NewMockTokenAccessor(ctrl)
   602  	mockTokenAccessor.EXPECT().Sign(gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil).AnyTimes()
   603  	mockTokenAccessor.EXPECT().CreateSynPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2).Return([]byte("token"), nil)
   604  
   605  	dp, conn, err := setupDatapathAndPUs(ctrl, mockCollector, mockTokenAccessor)
   606  	require.Nil(t, err)
   607  	require.NotNil(t, dp)
   608  
   609  	item, err := dp.puFromContextID.Get(testPU1CtxID)
   610  	require.Nil(t, err)
   611  	require.NotNil(t, item)
   612  	puctx1 := item.(*pucontext.PUContext)
   613  
   614  	item, err = dp.puFromContextID.Get(testPU2CtxID)
   615  	require.Nil(t, err)
   616  	require.NotNil(t, item)
   617  	puctx2 := item.(*pucontext.PUContext)
   618  
   619  	pc := &policy.PingConfig{
   620  		ID:                "5e9e38ad39483e772044095e",
   621  		IP:                dip,
   622  		Port:              dpt,
   623  		Iterations:        1,
   624  		TargetTCPNetworks: true,
   625  		ExcludedNetworks:  false,
   626  	}
   627  
   628  	pingPayload := &policy.PingPayload{
   629  		PingID:               pc.ID,
   630  		IterationID:          0,
   631  		ApplicationListening: false,
   632  		NamespaceHash:        testPU1NSHash,
   633  	}
   634  
   635  	puctx1.UpdateApplicationACLs( // nolint: errcheck
   636  		policy.IPRuleList{
   637  			policy.IPRule{
   638  				Addresses: []string{"0.0.0.0/0"},
   639  				Ports:     []string{"1:65535"},
   640  				Protocols: []string{"6", "17"},
   641  				Policy: &policy.FlowPolicy{
   642  					Action:   policy.Accept,
   643  					PolicyID: "extnetidabc",
   644  				},
   645  			},
   646  		},
   647  	)
   648  
   649  	mockTokenAccessor.EXPECT().CreateSynPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return([]byte("token"), nil)
   650  
   651  	err = dp.Ping(context.Background(), testPU1CtxID, pc)
   652  	require.Nil(t, err)
   653  
   654  	// NetSyn
   655  	ipPacket, err := wrapIP(conn.data(), false, false, tcp.Syn)
   656  	require.Nil(t, err)
   657  
   658  	p, err := packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
   659  	require.Nil(t, err)
   660  	require.NotNil(t, p)
   661  	payloadSize := len(p.ReadTCPData())
   662  	tcpConn := connection.NewTCPConnection(puctx2, p)
   663  	tcpConn.SourceController = srcCtrl
   664  	pkt := &policy.FlowPolicy{Action: policy.Accept, PolicyID: "abc"}
   665  
   666  	ts := policy.NewTagStore()
   667  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU1CtxID)
   668  	claims := &tokens.ConnectionClaims{
   669  		P: pingPayload,
   670  		T: ts,
   671  	}
   672  
   673  	pr := &collector.PingReport{
   674  		PingID:               pc.ID,
   675  		IterationID:          0,
   676  		Type:                 gaia.PingProbeTypeRequest,
   677  		PUID:                 testPU2CtxID,
   678  		RemotePUID:           testPU1CtxID,
   679  		Namespace:            testPU2NS,
   680  		FourTuple:            "192.168.100.1:172.17.0.2:2020:80",
   681  		RTT:                  "",
   682  		Protocol:             6,
   683  		ServiceType:          "L3",
   684  		PayloadSize:          payloadSize,
   685  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
   686  		PolicyID:             "abc",
   687  		PolicyAction:         policy.Accept,
   688  		AgentVersion:         "0.0.0",
   689  		ApplicationListening: false,
   690  		RemoteEndpointType:   collector.EndPointTypePU,
   691  		SeqNum:               seqnum,
   692  		TargetTCPNetworks:    true,
   693  		ExcludedNetworks:     false,
   694  		Claims:               []string{"a=b"},
   695  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
   696  		RemoteNamespace:      testPU1NSHash,
   697  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
   698  		ACLPolicyID:          "",
   699  		ACLPolicyAction:      policy.ActionType(0),
   700  		RemoteController:     srcCtrl,
   701  		IsServer:             true,
   702  	}
   703  
   704  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
   705  	copiedData, err := copystructure.Copy(pingPayload)
   706  	synAckPayload := copiedData.(*policy.PingPayload)
   707  	synAckPayload.NamespaceHash = testPU2NSHash
   708  	require.Nil(t, err)
   709  	mockTokenAccessor.EXPECT().CreateSynAckPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return([]byte("token"), nil)
   710  
   711  	oldsynAckDelay := synAckDelay
   712  	synAckDelay = 1 * time.Second
   713  	defer func() {
   714  		synAckDelay = oldsynAckDelay
   715  	}()
   716  
   717  	switchAppListening(true)
   718  	err = dp.processPingNetSynPacket(puctx2, tcpConn, p, payloadSize, pkt, claims)
   719  	require.Nil(t, err)
   720  
   721  	time.Sleep(2 * time.Second)
   722  
   723  	// NetSynAck
   724  	ipPacket, err = wrapIP(conn.data(), true, false, tcp.Syn|tcp.Ack)
   725  	require.Nil(t, err)
   726  
   727  	p, err = packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
   728  	require.Nil(t, err)
   729  	require.NotNil(t, p)
   730  
   731  	item1, exists := dp.tcpClient.Get(p.L4ReverseFlowHash())
   732  	if !exists {
   733  		t.Fail()
   734  	}
   735  
   736  	tcpConn = item1
   737  	tcpConn.DestinationController = dstCtrl
   738  
   739  	pkt = &policy.FlowPolicy{Action: policy.Accept, PolicyID: "abc"}
   740  
   741  	ts = policy.NewTagStore()
   742  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU2CtxID)
   743  	claims = &tokens.ConnectionClaims{
   744  		P: pingPayload,
   745  		T: ts,
   746  	}
   747  
   748  	pr = &collector.PingReport{
   749  		PingID:               pc.ID,
   750  		IterationID:          0,
   751  		Type:                 gaia.PingProbeTypeResponse,
   752  		PUID:                 testPU1CtxID,
   753  		RemotePUID:           testPU2CtxID,
   754  		Namespace:            testPU1NS,
   755  		FourTuple:            "172.17.0.2:192.168.100.1:80:2020",
   756  		RTT:                  duration,
   757  		Protocol:             6,
   758  		ServiceType:          "L3",
   759  		PayloadSize:          payloadSize,
   760  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
   761  		PolicyID:             "abc",
   762  		PolicyAction:         policy.Accept,
   763  		AgentVersion:         "0.0.0",
   764  		ApplicationListening: false,
   765  		RemoteEndpointType:   collector.EndPointTypePU,
   766  		SeqNum:               seqnum,
   767  		TargetTCPNetworks:    true,
   768  		ExcludedNetworks:     false,
   769  		Claims:               []string{"x=y"},
   770  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
   771  		RemoteNamespace:      testPU2NSHash,
   772  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
   773  		ACLPolicyID:          "extnetidabc",
   774  		ACLPolicyAction:      policy.Accept,
   775  		RemoteController:     dstCtrl,
   776  	}
   777  
   778  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
   779  
   780  	claims.P.NamespaceHash = testPU2NSHash
   781  	err = dp.processPingNetSynAckPacket(puctx1, tcpConn, p, payloadSize, pkt, claims, false)
   782  	require.Equal(t, errDropPingNetSynAck, err)
   783  }
   784  
   785  func Test_ValidPingReject(t *testing.T) {
   786  
   787  	ctrl := gomock.NewController(t)
   788  	defer ctrl.Finish()
   789  
   790  	mockCollector := mockcollector.NewMockEventCollector(ctrl)
   791  	mockTokenAccessor := mocktokenaccessor.NewMockTokenAccessor(ctrl)
   792  	mockTokenAccessor.EXPECT().Sign(gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil).AnyTimes()
   793  	mockTokenAccessor.EXPECT().CreateSynPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil)
   794  
   795  	dp, conn, err := setupDatapathAndPUs(ctrl, mockCollector, mockTokenAccessor)
   796  	require.Nil(t, err)
   797  	require.NotNil(t, dp)
   798  
   799  	item, err := dp.puFromContextID.Get(testPU1CtxID)
   800  	require.Nil(t, err)
   801  	require.NotNil(t, item)
   802  	puctx1 := item.(*pucontext.PUContext)
   803  
   804  	item, err = dp.puFromContextID.Get(testPU2CtxID)
   805  	require.Nil(t, err)
   806  	require.NotNil(t, item)
   807  	puctx2 := item.(*pucontext.PUContext)
   808  
   809  	pc := &policy.PingConfig{
   810  		ID:                "5e9e38ad39483e772044095e",
   811  		IP:                dip,
   812  		Port:              dpt,
   813  		Iterations:        1,
   814  		TargetTCPNetworks: true,
   815  		ExcludedNetworks:  false,
   816  	}
   817  
   818  	pingPayload := &policy.PingPayload{
   819  		PingID:               pc.ID,
   820  		IterationID:          0,
   821  		ApplicationListening: false,
   822  		NamespaceHash:        testPU1NSHash,
   823  	}
   824  
   825  	puctx1.UpdateApplicationACLs( // nolint: errcheck
   826  		policy.IPRuleList{
   827  			policy.IPRule{
   828  				Addresses: []string{"0.0.0.0/0"},
   829  				Ports:     []string{"1:65535"},
   830  				Protocols: []string{"6", "17"},
   831  				Policy: &policy.FlowPolicy{
   832  					Action:   policy.Accept,
   833  					PolicyID: "extnetidabc",
   834  				},
   835  			},
   836  		},
   837  	)
   838  
   839  	err = dp.Ping(context.Background(), testPU1CtxID, pc)
   840  	require.Nil(t, err)
   841  
   842  	// NetSyn
   843  	ipPacket, err := wrapIP(conn.data(), false, false, tcp.Syn)
   844  	require.Nil(t, err)
   845  
   846  	p, err := packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
   847  	require.Nil(t, err)
   848  	require.NotNil(t, p)
   849  	payloadSize := len(p.ReadTCPData())
   850  	tcpConn := connection.NewTCPConnection(puctx2, p)
   851  	tcpConn.SourceController = srcCtrl
   852  	pkt := &policy.FlowPolicy{Action: policy.Reject, PolicyID: "xyz"}
   853  
   854  	ts := policy.NewTagStore()
   855  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU1CtxID)
   856  	claims := &tokens.ConnectionClaims{
   857  		P: pingPayload,
   858  		T: ts,
   859  	}
   860  
   861  	pr := &collector.PingReport{
   862  		PingID:               pc.ID,
   863  		IterationID:          0,
   864  		Type:                 gaia.PingProbeTypeRequest,
   865  		PUID:                 testPU2CtxID,
   866  		RemotePUID:           testPU1CtxID,
   867  		Namespace:            testPU2NS,
   868  		FourTuple:            "192.168.100.1:172.17.0.2:2020:80",
   869  		RTT:                  "",
   870  		Protocol:             6,
   871  		ServiceType:          "L3",
   872  		PayloadSize:          payloadSize,
   873  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
   874  		PolicyID:             "xyz",
   875  		PolicyAction:         policy.Reject,
   876  		AgentVersion:         "0.0.0",
   877  		ApplicationListening: false,
   878  		RemoteEndpointType:   collector.EndPointTypePU,
   879  		SeqNum:               seqnum,
   880  		TargetTCPNetworks:    true,
   881  		ExcludedNetworks:     false,
   882  		Claims:               []string{"a=b"},
   883  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
   884  		RemoteNamespace:      testPU1NSHash,
   885  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
   886  		ACLPolicyID:          "",
   887  		ACLPolicyAction:      policy.ActionType(0),
   888  		RemoteController:     srcCtrl,
   889  		IsServer:             true,
   890  		Error:                collector.PolicyDrop,
   891  	}
   892  
   893  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
   894  	copiedData, err := copystructure.Copy(pingPayload)
   895  	synAckPayload := copiedData.(*policy.PingPayload)
   896  	synAckPayload.NamespaceHash = testPU2NSHash
   897  	require.Nil(t, err)
   898  	mockTokenAccessor.EXPECT().CreateSynAckPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return([]byte("token"), nil)
   899  
   900  	oldsynAckDelay := synAckDelay
   901  	synAckDelay = 1 * time.Second
   902  	defer func() {
   903  		synAckDelay = oldsynAckDelay
   904  	}()
   905  
   906  	err = dp.processPingNetSynPacket(puctx2, tcpConn, p, payloadSize, pkt, claims)
   907  	require.Equal(t, errDropPingNetSyn, err)
   908  
   909  	time.Sleep(2 * time.Second)
   910  
   911  	// NetSynAck
   912  	ipPacket, err = wrapIP(conn.data(), true, false, tcp.Syn|tcp.Ack)
   913  	require.Nil(t, err)
   914  
   915  	p, err = packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
   916  	require.Nil(t, err)
   917  	require.NotNil(t, p)
   918  
   919  	item1, exists := dp.tcpClient.Get(p.L4ReverseFlowHash())
   920  	if !exists {
   921  		t.Fail()
   922  	}
   923  	tcpConn = item1
   924  	tcpConn.DestinationController = dstCtrl
   925  
   926  	pkt = &policy.FlowPolicy{Action: policy.Accept, PolicyID: "abc"}
   927  
   928  	ts = policy.NewTagStore()
   929  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU2CtxID)
   930  	claims = &tokens.ConnectionClaims{
   931  		P: pingPayload,
   932  		T: ts,
   933  	}
   934  
   935  	pr = &collector.PingReport{
   936  		PingID:               pc.ID,
   937  		IterationID:          0,
   938  		Type:                 gaia.PingProbeTypeResponse,
   939  		PUID:                 testPU1CtxID,
   940  		RemotePUID:           testPU2CtxID,
   941  		Namespace:            testPU1NS,
   942  		FourTuple:            "172.17.0.2:192.168.100.1:80:2020",
   943  		RTT:                  duration,
   944  		Protocol:             6,
   945  		ServiceType:          "L3",
   946  		PayloadSize:          payloadSize,
   947  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
   948  		PolicyID:             "abc",
   949  		PolicyAction:         policy.Accept,
   950  		AgentVersion:         "0.0.0",
   951  		ApplicationListening: false,
   952  		RemoteEndpointType:   collector.EndPointTypePU,
   953  		SeqNum:               seqnum,
   954  		TargetTCPNetworks:    true,
   955  		ExcludedNetworks:     false,
   956  		Claims:               []string{"x=y"},
   957  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
   958  		RemoteNamespace:      testPU2NSHash,
   959  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
   960  		ACLPolicyID:          "extnetidabc",
   961  		ACLPolicyAction:      policy.Accept,
   962  		RemoteController:     dstCtrl,
   963  	}
   964  
   965  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
   966  
   967  	claims.P.NamespaceHash = testPU2NSHash
   968  	err = dp.processPingNetSynAckPacket(puctx1, tcpConn, p, payloadSize, pkt, claims, false)
   969  	require.Equal(t, errDropPingNetSynAck, err)
   970  }
   971  
   972  func Test_ValidPingUnequalSeqNum(t *testing.T) {
   973  
   974  	ctrl := gomock.NewController(t)
   975  	defer ctrl.Finish()
   976  
   977  	mockCollector := mockcollector.NewMockEventCollector(ctrl)
   978  	mockTokenAccessor := mocktokenaccessor.NewMockTokenAccessor(ctrl)
   979  
   980  	mockTokenAccessor.EXPECT().Sign(gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil).AnyTimes()
   981  	mockTokenAccessor.EXPECT().CreateSynPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil)
   982  
   983  	dp, conn, err := setupDatapathAndPUs(ctrl, mockCollector, mockTokenAccessor)
   984  	require.Nil(t, err)
   985  	require.NotNil(t, dp)
   986  
   987  	item, err := dp.puFromContextID.Get(testPU1CtxID)
   988  	require.Nil(t, err)
   989  	require.NotNil(t, item)
   990  	puctx1 := item.(*pucontext.PUContext)
   991  
   992  	item, err = dp.puFromContextID.Get(testPU2CtxID)
   993  	require.Nil(t, err)
   994  	require.NotNil(t, item)
   995  	puctx2 := item.(*pucontext.PUContext)
   996  
   997  	pc := &policy.PingConfig{
   998  		ID:                "5e9e38ad39483e772044095e",
   999  		IP:                dip,
  1000  		Port:              dpt,
  1001  		Iterations:        1,
  1002  		TargetTCPNetworks: true,
  1003  		ExcludedNetworks:  false,
  1004  	}
  1005  
  1006  	pingPayload := &policy.PingPayload{
  1007  		PingID:               pc.ID,
  1008  		IterationID:          0,
  1009  		ApplicationListening: false,
  1010  		NamespaceHash:        testPU1NSHash,
  1011  	}
  1012  
  1013  	err = dp.Ping(context.Background(), testPU1CtxID, pc)
  1014  	require.Nil(t, err)
  1015  
  1016  	// NetSyn
  1017  	ipPacket, err := wrapIP(conn.data(), false, true, tcp.Syn)
  1018  	require.Nil(t, err)
  1019  
  1020  	p, err := packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
  1021  	require.Nil(t, err)
  1022  	require.NotNil(t, p)
  1023  	payloadSize := len(p.ReadTCPData())
  1024  	tcpConn := connection.NewTCPConnection(puctx2, p)
  1025  	pkt := &policy.FlowPolicy{Action: policy.Accept, PolicyID: "abc"}
  1026  
  1027  	ts := policy.NewTagStore()
  1028  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU1CtxID)
  1029  	claims := &tokens.ConnectionClaims{
  1030  		P: pingPayload,
  1031  		T: ts,
  1032  	}
  1033  
  1034  	pr := &collector.PingReport{
  1035  		PingID:               pc.ID,
  1036  		IterationID:          0,
  1037  		Type:                 gaia.PingProbeTypeRequest,
  1038  		PUID:                 testPU2CtxID,
  1039  		RemotePUID:           testPU1CtxID,
  1040  		Namespace:            testPU2NS,
  1041  		FourTuple:            "192.168.100.1:172.17.0.2:2020:80",
  1042  		RTT:                  "",
  1043  		Protocol:             6,
  1044  		ServiceType:          "L3",
  1045  		PayloadSize:          payloadSize,
  1046  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
  1047  		PolicyID:             "abc",
  1048  		PolicyAction:         policy.Accept,
  1049  		AgentVersion:         "0.0.0",
  1050  		ApplicationListening: false,
  1051  		RemoteEndpointType:   collector.EndPointTypePU,
  1052  		SeqNum:               111111,
  1053  		TargetTCPNetworks:    true,
  1054  		ExcludedNetworks:     false,
  1055  		Claims:               []string{"a=b"},
  1056  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
  1057  		RemoteNamespace:      testPU1NSHash,
  1058  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
  1059  		ACLPolicyID:          "",
  1060  		ACLPolicyAction:      policy.ActionType(0),
  1061  		IsServer:             true,
  1062  	}
  1063  
  1064  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
  1065  	copiedData, err := copystructure.Copy(pingPayload)
  1066  	synAckPayload := copiedData.(*policy.PingPayload)
  1067  	synAckPayload.NamespaceHash = testPU2NSHash
  1068  	require.Nil(t, err)
  1069  	mockTokenAccessor.EXPECT().CreateSynAckPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return([]byte("token"), nil)
  1070  
  1071  	oldsynAckDelay := synAckDelay
  1072  	synAckDelay = 1 * time.Second
  1073  	defer func() {
  1074  		synAckDelay = oldsynAckDelay
  1075  	}()
  1076  
  1077  	err = dp.processPingNetSynPacket(puctx2, tcpConn, p, payloadSize, pkt, claims)
  1078  	require.Equal(t, errDropPingNetSyn, err)
  1079  
  1080  	time.Sleep(2 * time.Second)
  1081  
  1082  	// NetSynAck
  1083  	ipPacket, err = wrapIP(conn.data(), true, false, tcp.Syn|tcp.Ack)
  1084  	require.Nil(t, err)
  1085  
  1086  	p, err = packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
  1087  	require.Nil(t, err)
  1088  	require.NotNil(t, p)
  1089  	payloadSize = len(p.ReadTCPData())
  1090  
  1091  	item1, _ := dp.tcpClient.Get(p.L4ReverseFlowHash())
  1092  	tcpConn = item1
  1093  
  1094  	pkt = &policy.FlowPolicy{Action: policy.Reject, PolicyID: "cde"}
  1095  
  1096  	ts = policy.NewTagStore()
  1097  	ts.AppendKeyValue(enforcerconstants.TransmitterLabel, testPU2CtxID)
  1098  	claims = &tokens.ConnectionClaims{
  1099  		P: pingPayload,
  1100  		T: ts,
  1101  	}
  1102  
  1103  	pr = &collector.PingReport{
  1104  		PingID:               pc.ID,
  1105  		IterationID:          0,
  1106  		Type:                 gaia.PingProbeTypeResponse,
  1107  		PUID:                 testPU1CtxID,
  1108  		RemotePUID:           testPU2CtxID,
  1109  		Namespace:            testPU1NS,
  1110  		FourTuple:            "172.17.0.2:192.168.100.1:80:2020",
  1111  		RTT:                  duration,
  1112  		Protocol:             6,
  1113  		ServiceType:          "L3",
  1114  		PayloadSize:          payloadSize,
  1115  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
  1116  		PolicyID:             "cde",
  1117  		PolicyAction:         policy.Reject,
  1118  		AgentVersion:         "0.0.0",
  1119  		ApplicationListening: false,
  1120  		RemoteEndpointType:   collector.EndPointTypePU,
  1121  		SeqNum:               seqnum,
  1122  		TargetTCPNetworks:    true,
  1123  		ExcludedNetworks:     false,
  1124  		RemoteNamespace:      testPU2NSHash,
  1125  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
  1126  		Claims:               []string{"x=y"},
  1127  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
  1128  		ACLPolicyID:          "default",
  1129  		ACLPolicyAction:      policy.Reject | policy.Log,
  1130  		Error:                collector.PolicyDrop,
  1131  	}
  1132  
  1133  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
  1134  	claims.P.NamespaceHash = testPU2NSHash
  1135  	err = dp.processPingNetSynAckPacket(puctx1, tcpConn, p, payloadSize, pkt, claims, false)
  1136  	require.Equal(t, errDropPingNetSynAck, err)
  1137  }
  1138  
  1139  func Test_ValidPingExtNet(t *testing.T) {
  1140  
  1141  	ctrl := gomock.NewController(t)
  1142  	defer ctrl.Finish()
  1143  
  1144  	mockCollector := mockcollector.NewMockEventCollector(ctrl)
  1145  	mockTokenAccessor := mocktokenaccessor.NewMockTokenAccessor(ctrl)
  1146  
  1147  	mockTokenAccessor.EXPECT().Sign(gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil).AnyTimes()
  1148  	mockTokenAccessor.EXPECT().CreateSynPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil)
  1149  
  1150  	dp, conn, err := setupDatapathAndPUs(ctrl, mockCollector, mockTokenAccessor)
  1151  	require.Nil(t, err)
  1152  	require.NotNil(t, dp)
  1153  
  1154  	item, err := dp.puFromContextID.Get(testPU1CtxID)
  1155  	require.Nil(t, err)
  1156  	require.NotNil(t, item)
  1157  	puctx1 := item.(*pucontext.PUContext)
  1158  
  1159  	pc := &policy.PingConfig{
  1160  		ID:                "5e9e38ad39483e772044095e",
  1161  		IP:                dip,
  1162  		Port:              dpt,
  1163  		Iterations:        1,
  1164  		TargetTCPNetworks: true,
  1165  		ExcludedNetworks:  false,
  1166  	}
  1167  
  1168  	err = dp.Ping(context.Background(), testPU1CtxID, pc)
  1169  	require.Nil(t, err)
  1170  
  1171  	// NetSynAck
  1172  	ipPacket, err := wrapIP(conn.data(), true, false, tcp.Syn)
  1173  	require.Nil(t, err)
  1174  
  1175  	p, err := packet.New(packet.PacketTypeNetwork, ipPacket, "0", false)
  1176  	require.Nil(t, err)
  1177  	require.NotNil(t, p)
  1178  	payloadSize := len(p.ReadTCPData())
  1179  
  1180  	item1, _ := dp.tcpClient.Get(p.L4ReverseFlowHash())
  1181  	tcpConn := item1
  1182  
  1183  	pkt := &policy.FlowPolicy{Action: policy.Accept, PolicyID: "abc"}
  1184  
  1185  	pr := &collector.PingReport{
  1186  		PingID:               pc.ID,
  1187  		IterationID:          0,
  1188  		Type:                 gaia.PingProbeTypeResponse,
  1189  		PUID:                 testPU1CtxID,
  1190  		Namespace:            testPU1NS,
  1191  		FourTuple:            "172.17.0.2:192.168.100.1:80:2020",
  1192  		RTT:                  duration,
  1193  		Protocol:             6,
  1194  		ServiceType:          "L3",
  1195  		PayloadSize:          payloadSize,
  1196  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeReceived,
  1197  		PolicyID:             "abc",
  1198  		PolicyAction:         policy.Accept,
  1199  		AgentVersion:         "0.0.0",
  1200  		ApplicationListening: true,
  1201  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
  1202  		RemoteEndpointType:   collector.EndPointTypeExternalIP,
  1203  		SeqNum:               seqnum,
  1204  		TargetTCPNetworks:    true,
  1205  		ExcludedNetworks:     false,
  1206  		Claims:               []string{"x=y"},
  1207  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
  1208  		ACLPolicyID:          "default",
  1209  		ACLPolicyAction:      policy.Reject | policy.Log,
  1210  	}
  1211  
  1212  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
  1213  
  1214  	// NOTE: Overriding the default conn timeout of 15s to 3s.
  1215  	oldremoveDelay := removeDelay
  1216  	removeDelay = 2 * time.Second
  1217  	defer func() {
  1218  		removeDelay = oldremoveDelay
  1219  	}()
  1220  
  1221  	tcpConn.ChangeConnectionTimeout(3 * time.Second)
  1222  	err = dp.processPingNetSynAckPacket(puctx1, tcpConn, p, payloadSize, pkt, nil, true)
  1223  	require.Equal(t, errDropPingNetSynAck, err)
  1224  
  1225  	require.Equal(t, connection.TCPSynAckReceived, tcpConn.GetState())
  1226  
  1227  	time.Sleep(4 * time.Second)
  1228  
  1229  	_, exists := dp.tcpClient.Get(p.L4ReverseFlowHash())
  1230  	if exists {
  1231  		t.Fail()
  1232  	}
  1233  }
  1234  
  1235  func Test_PingRequestTimeout(t *testing.T) {
  1236  
  1237  	ctrl := gomock.NewController(t)
  1238  	defer ctrl.Finish()
  1239  
  1240  	mockCollector := mockcollector.NewMockEventCollector(ctrl)
  1241  	mockTokenAccessor := mocktokenaccessor.NewMockTokenAccessor(ctrl)
  1242  
  1243  	mockTokenAccessor.EXPECT().Sign(gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil).AnyTimes()
  1244  	mockTokenAccessor.EXPECT().CreateSynPacketToken(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3).Return([]byte("token"), nil)
  1245  
  1246  	dp, _, err := setupDatapathAndPUs(ctrl, mockCollector, mockTokenAccessor)
  1247  	require.Nil(t, err)
  1248  	require.NotNil(t, dp)
  1249  
  1250  	pc := &policy.PingConfig{
  1251  		ID:                "5e9e38ad39483e772044095e",
  1252  		IP:                dip,
  1253  		Port:              dpt,
  1254  		Iterations:        1,
  1255  		TargetTCPNetworks: true,
  1256  		ExcludedNetworks:  true,
  1257  	}
  1258  
  1259  	pr := &collector.PingReport{
  1260  		PingID:               pc.ID,
  1261  		IterationID:          0,
  1262  		Type:                 gaia.PingProbeTypeRequest,
  1263  		PUID:                 testPU1CtxID,
  1264  		Namespace:            testPU1NS,
  1265  		FourTuple:            "192.168.100.1:172.17.0.2:2020:80",
  1266  		RTT:                  "",
  1267  		Protocol:             6,
  1268  		ServiceType:          "L3",
  1269  		PayloadSize:          5,
  1270  		PayloadSizeType:      gaia.PingProbePayloadSizeTypeTransmitted,
  1271  		PolicyID:             "",
  1272  		PolicyAction:         policy.ActionType(0), // Not a valid action, defaults to "unknown"
  1273  		AgentVersion:         "0.0.0",
  1274  		ApplicationListening: false,
  1275  		SeqNum:               seqnum,
  1276  		RemoteNamespaceType:  gaia.PingProbeRemoteNamespaceTypeHash,
  1277  		TargetTCPNetworks:    true,
  1278  		ExcludedNetworks:     true,
  1279  		Claims:               []string{"x=y"},
  1280  		ClaimsType:           gaia.PingProbeClaimsTypeTransmitted,
  1281  		ACLPolicyID:          "default",
  1282  		ACLPolicyAction:      policy.Reject | policy.Log,
  1283  		Error:                policy.ErrExcludedNetworks,
  1284  	}
  1285  
  1286  	mockCollector.EXPECT().CollectPingEvent(pr).Times(1)
  1287  
  1288  	oldconnTimeout := connection.DefaultConnectionTimeout
  1289  	connection.DefaultConnectionTimeout = 3 * time.Second
  1290  	defer func() {
  1291  		connection.DefaultConnectionTimeout = oldconnTimeout
  1292  	}()
  1293  
  1294  	err = dp.Ping(context.Background(), testPU1CtxID, pc)
  1295  	require.Nil(t, err)
  1296  	time.Sleep(4 * time.Second)
  1297  
  1298  	list := dp.tcpClient.Len()
  1299  	if list != 0 {
  1300  		t.Fail()
  1301  	}
  1302  }