github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/packetimpact/tests/fin_wait2_timeout_test.go (about)

     1  // Copyright 2020 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package fin_wait2_timeout_test
    16  
    17  import (
    18  	"flag"
    19  	"testing"
    20  	"time"
    21  
    22  	"golang.org/x/sys/unix"
    23  	"github.com/SagerNet/gvisor/pkg/tcpip/header"
    24  	"github.com/SagerNet/gvisor/test/packetimpact/testbench"
    25  )
    26  
    27  func init() {
    28  	testbench.Initialize(flag.CommandLine)
    29  }
    30  
    31  func TestFinWait2Timeout(t *testing.T) {
    32  	for _, tt := range []struct {
    33  		description string
    34  		linger2     bool
    35  	}{
    36  		{"WithLinger2", true},
    37  		{"WithoutLinger2", false},
    38  	} {
    39  		t.Run(tt.description, func(t *testing.T) {
    40  			dut := testbench.NewDUT(t)
    41  			listenFd, remotePort := dut.CreateListener(t, unix.SOCK_STREAM, unix.IPPROTO_TCP, 1)
    42  			defer dut.Close(t, listenFd)
    43  			conn := dut.Net.NewTCPIPv4(t, testbench.TCP{DstPort: &remotePort}, testbench.TCP{SrcPort: &remotePort})
    44  			defer conn.Close(t)
    45  			conn.Connect(t)
    46  
    47  			acceptFd, _ := dut.Accept(t, listenFd)
    48  			if tt.linger2 {
    49  				tv := unix.Timeval{Sec: 1, Usec: 0}
    50  				dut.SetSockOptTimeval(t, acceptFd, unix.SOL_TCP, unix.TCP_LINGER2, &tv)
    51  			}
    52  			dut.Close(t, acceptFd)
    53  
    54  			if _, err := conn.Expect(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagFin | header.TCPFlagAck)}, time.Second); err != nil {
    55  				t.Fatalf("expected a FIN-ACK within 1 second but got none: %s", err)
    56  			}
    57  			conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
    58  
    59  			time.Sleep(5 * time.Second)
    60  			conn.Drain(t)
    61  
    62  			conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagAck)})
    63  			if tt.linger2 {
    64  				if _, err := conn.Expect(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagRst)}, time.Second); err != nil {
    65  					t.Fatalf("expected a RST packet within a second but got none: %s", err)
    66  				}
    67  			} else {
    68  				if got, err := conn.Expect(t, testbench.TCP{Flags: testbench.TCPFlags(header.TCPFlagRst)}, 10*time.Second); got != nil || err == nil {
    69  					t.Fatalf("expected no RST packets within ten seconds but got one: %s", got)
    70  				}
    71  			}
    72  		})
    73  	}
    74  }