Source file src/net/rawconn_test.go

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !js
     6  
     7  package net
     8  
     9  import (
    10  	"bytes"
    11  	"runtime"
    12  	"testing"
    13  	"time"
    14  )
    15  
    16  func TestRawConnReadWrite(t *testing.T) {
    17  	switch runtime.GOOS {
    18  	case "plan9":
    19  		t.Skipf("not supported on %s", runtime.GOOS)
    20  	}
    21  
    22  	t.Run("TCP", func(t *testing.T) {
    23  		handler := func(ls *localServer, ln Listener) {
    24  			c, err := ln.Accept()
    25  			if err != nil {
    26  				t.Error(err)
    27  				return
    28  			}
    29  			defer c.Close()
    30  
    31  			cc, err := ln.(*TCPListener).SyscallConn()
    32  			if err != nil {
    33  				t.Fatal(err)
    34  			}
    35  			called := false
    36  			op := func(uintptr) bool {
    37  				called = true
    38  				return true
    39  			}
    40  			err = cc.Write(op)
    41  			if err == nil {
    42  				t.Error("Write should return an error")
    43  			}
    44  			if called {
    45  				t.Error("Write shouldn't call op")
    46  			}
    47  			called = false
    48  			err = cc.Read(op)
    49  			if err == nil {
    50  				t.Error("Read should return an error")
    51  			}
    52  			if called {
    53  				t.Error("Read shouldn't call op")
    54  			}
    55  
    56  			var b [32]byte
    57  			n, err := c.Read(b[:])
    58  			if err != nil {
    59  				t.Error(err)
    60  				return
    61  			}
    62  			if _, err := c.Write(b[:n]); err != nil {
    63  				t.Error(err)
    64  				return
    65  			}
    66  		}
    67  		ls := newLocalServer(t, "tcp")
    68  		defer ls.teardown()
    69  		if err := ls.buildup(handler); err != nil {
    70  			t.Fatal(err)
    71  		}
    72  
    73  		c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
    74  		if err != nil {
    75  			t.Fatal(err)
    76  		}
    77  		defer c.Close()
    78  
    79  		cc, err := c.(*TCPConn).SyscallConn()
    80  		if err != nil {
    81  			t.Fatal(err)
    82  		}
    83  		data := []byte("HELLO-R-U-THERE")
    84  		if err := writeRawConn(cc, data); err != nil {
    85  			t.Fatal(err)
    86  		}
    87  		var b [32]byte
    88  		n, err := readRawConn(cc, b[:])
    89  		if err != nil {
    90  			t.Fatal(err)
    91  		}
    92  		if bytes.Compare(b[:n], data) != 0 {
    93  			t.Fatalf("got %q; want %q", b[:n], data)
    94  		}
    95  	})
    96  	t.Run("Deadline", func(t *testing.T) {
    97  		switch runtime.GOOS {
    98  		case "windows":
    99  			t.Skipf("not supported on %s", runtime.GOOS)
   100  		}
   101  
   102  		ln := newLocalListener(t, "tcp")
   103  		defer ln.Close()
   104  
   105  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   106  		if err != nil {
   107  			t.Fatal(err)
   108  		}
   109  		defer c.Close()
   110  
   111  		cc, err := c.(*TCPConn).SyscallConn()
   112  		if err != nil {
   113  			t.Fatal(err)
   114  		}
   115  		var b [1]byte
   116  
   117  		c.SetDeadline(noDeadline)
   118  		if err := c.SetDeadline(time.Now().Add(-1)); err != nil {
   119  			t.Fatal(err)
   120  		}
   121  		if err = writeRawConn(cc, b[:]); err == nil {
   122  			t.Fatal("Write should fail")
   123  		}
   124  		if perr := parseWriteError(err); perr != nil {
   125  			t.Error(perr)
   126  		}
   127  		if !isDeadlineExceeded(err) {
   128  			t.Errorf("got %v; want timeout", err)
   129  		}
   130  		if _, err = readRawConn(cc, b[:]); err == nil {
   131  			t.Fatal("Read should fail")
   132  		}
   133  		if perr := parseReadError(err); perr != nil {
   134  			t.Error(perr)
   135  		}
   136  		if !isDeadlineExceeded(err) {
   137  			t.Errorf("got %v; want timeout", err)
   138  		}
   139  
   140  		c.SetReadDeadline(noDeadline)
   141  		if err := c.SetReadDeadline(time.Now().Add(-1)); err != nil {
   142  			t.Fatal(err)
   143  		}
   144  		if _, err = readRawConn(cc, b[:]); err == nil {
   145  			t.Fatal("Read should fail")
   146  		}
   147  		if perr := parseReadError(err); perr != nil {
   148  			t.Error(perr)
   149  		}
   150  		if !isDeadlineExceeded(err) {
   151  			t.Errorf("got %v; want timeout", err)
   152  		}
   153  
   154  		c.SetWriteDeadline(noDeadline)
   155  		if err := c.SetWriteDeadline(time.Now().Add(-1)); err != nil {
   156  			t.Fatal(err)
   157  		}
   158  		if err = writeRawConn(cc, b[:]); err == nil {
   159  			t.Fatal("Write should fail")
   160  		}
   161  		if perr := parseWriteError(err); perr != nil {
   162  			t.Error(perr)
   163  		}
   164  		if !isDeadlineExceeded(err) {
   165  			t.Errorf("got %v; want timeout", err)
   166  		}
   167  	})
   168  }
   169  
   170  func TestRawConnControl(t *testing.T) {
   171  	switch runtime.GOOS {
   172  	case "plan9":
   173  		t.Skipf("not supported on %s", runtime.GOOS)
   174  	}
   175  
   176  	t.Run("TCP", func(t *testing.T) {
   177  		ln := newLocalListener(t, "tcp")
   178  		defer ln.Close()
   179  
   180  		cc1, err := ln.(*TCPListener).SyscallConn()
   181  		if err != nil {
   182  			t.Fatal(err)
   183  		}
   184  		if err := controlRawConn(cc1, ln.Addr()); err != nil {
   185  			t.Fatal(err)
   186  		}
   187  
   188  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   189  		if err != nil {
   190  			t.Fatal(err)
   191  		}
   192  		defer c.Close()
   193  
   194  		cc2, err := c.(*TCPConn).SyscallConn()
   195  		if err != nil {
   196  			t.Fatal(err)
   197  		}
   198  		if err := controlRawConn(cc2, c.LocalAddr()); err != nil {
   199  			t.Fatal(err)
   200  		}
   201  
   202  		ln.Close()
   203  		if err := controlRawConn(cc1, ln.Addr()); err == nil {
   204  			t.Fatal("Control after Close should fail")
   205  		}
   206  		c.Close()
   207  		if err := controlRawConn(cc2, c.LocalAddr()); err == nil {
   208  			t.Fatal("Control after Close should fail")
   209  		}
   210  	})
   211  }
   212  

View as plain text