github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/net/rawconn_test.go (about) 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 }