github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/net/rawconn_unix_test.go (about) 1 // Copyright 2017 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 // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 7 package net 8 9 import ( 10 "bytes" 11 "syscall" 12 "testing" 13 ) 14 15 func TestRawConn(t *testing.T) { 16 handler := func(ls *localServer, ln Listener) { 17 c, err := ln.Accept() 18 if err != nil { 19 t.Error(err) 20 return 21 } 22 defer c.Close() 23 var b [32]byte 24 n, err := c.Read(b[:]) 25 if err != nil { 26 t.Error(err) 27 return 28 } 29 if _, err := c.Write(b[:n]); err != nil { 30 t.Error(err) 31 return 32 } 33 } 34 ls, err := newLocalServer("tcp") 35 if err != nil { 36 t.Fatal(err) 37 } 38 defer ls.teardown() 39 if err := ls.buildup(handler); err != nil { 40 t.Fatal(err) 41 } 42 43 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 44 if err != nil { 45 t.Fatal(err) 46 } 47 defer c.Close() 48 cc, err := c.(*TCPConn).SyscallConn() 49 if err != nil { 50 t.Fatal(err) 51 } 52 53 var operr error 54 data := []byte("HELLO-R-U-THERE") 55 err = cc.Write(func(s uintptr) bool { 56 _, operr = syscall.Write(int(s), data) 57 if operr == syscall.EAGAIN { 58 return false 59 } 60 return true 61 }) 62 if err != nil || operr != nil { 63 t.Fatal(err, operr) 64 } 65 66 var nr int 67 var b [32]byte 68 err = cc.Read(func(s uintptr) bool { 69 nr, operr = syscall.Read(int(s), b[:]) 70 if operr == syscall.EAGAIN { 71 return false 72 } 73 return true 74 }) 75 if err != nil || operr != nil { 76 t.Fatal(err, operr) 77 } 78 if bytes.Compare(b[:nr], data) != 0 { 79 t.Fatalf("got %#v; want %#v", b[:nr], data) 80 } 81 82 fn := func(s uintptr) { 83 operr = syscall.SetsockoptInt(int(s), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) 84 } 85 err = cc.Control(fn) 86 if err != nil || operr != nil { 87 t.Fatal(err, operr) 88 } 89 c.Close() 90 err = cc.Control(fn) 91 if err == nil { 92 t.Fatal("should fail") 93 } 94 } 95 96 func TestRawConnListener(t *testing.T) { 97 ln, err := newLocalListener("tcp") 98 if err != nil { 99 t.Fatal(err) 100 } 101 defer ln.Close() 102 103 cc, err := ln.(*TCPListener).SyscallConn() 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 called := false 109 op := func(uintptr) bool { 110 called = true 111 return true 112 } 113 114 err = cc.Write(op) 115 if err == nil { 116 t.Error("Write should return an error") 117 } 118 if called { 119 t.Error("Write shouldn't call op") 120 } 121 122 called = false 123 err = cc.Read(op) 124 if err == nil { 125 t.Error("Read should return an error") 126 } 127 if called { 128 t.Error("Read shouldn't call op") 129 } 130 131 var operr error 132 fn := func(s uintptr) { 133 _, operr = syscall.GetsockoptInt(int(s), syscall.SOL_SOCKET, syscall.SO_REUSEADDR) 134 } 135 err = cc.Control(fn) 136 if err != nil || operr != nil { 137 t.Fatal(err, operr) 138 } 139 ln.Close() 140 err = cc.Control(fn) 141 if err == nil { 142 t.Fatal("Control after Close should fail") 143 } 144 }