Home | History | Annotate | Download | only in net
      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 package net
      6 
      7 import (
      8 	"syscall"
      9 	"testing"
     10 	"unsafe"
     11 )
     12 
     13 func TestRawConn(t *testing.T) {
     14 	c, err := newLocalPacketListener("udp")
     15 	if err != nil {
     16 		t.Fatal(err)
     17 	}
     18 	defer c.Close()
     19 	cc, err := c.(*UDPConn).SyscallConn()
     20 	if err != nil {
     21 		t.Fatal(err)
     22 	}
     23 
     24 	var operr error
     25 	fn := func(s uintptr) {
     26 		operr = syscall.SetsockoptInt(syscall.Handle(s), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
     27 	}
     28 	err = cc.Control(fn)
     29 	if err != nil || operr != nil {
     30 		t.Fatal(err, operr)
     31 	}
     32 	c.Close()
     33 	err = cc.Control(fn)
     34 	if err == nil {
     35 		t.Fatal("should fail")
     36 	}
     37 }
     38 
     39 func TestRawConnListener(t *testing.T) {
     40 	ln, err := newLocalListener("tcp")
     41 	if err != nil {
     42 		t.Fatal(err)
     43 	}
     44 	defer ln.Close()
     45 
     46 	cc, err := ln.(*TCPListener).SyscallConn()
     47 	if err != nil {
     48 		t.Fatal(err)
     49 	}
     50 
     51 	called := false
     52 	op := func(uintptr) bool {
     53 		called = true
     54 		return true
     55 	}
     56 
     57 	err = cc.Write(op)
     58 	if err == nil {
     59 		t.Error("Write should return an error")
     60 	}
     61 	if called {
     62 		t.Error("Write shouldn't call op")
     63 	}
     64 
     65 	called = false
     66 	err = cc.Read(op)
     67 	if err == nil {
     68 		t.Error("Read should return an error")
     69 	}
     70 	if called {
     71 		t.Error("Read shouldn't call op")
     72 	}
     73 
     74 	var operr error
     75 	fn := func(s uintptr) {
     76 		var v, l int32
     77 		l = int32(unsafe.Sizeof(v))
     78 		operr = syscall.Getsockopt(syscall.Handle(s), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, (*byte)(unsafe.Pointer(&v)), &l)
     79 	}
     80 	err = cc.Control(fn)
     81 	if err != nil || operr != nil {
     82 		t.Fatal(err, operr)
     83 	}
     84 	ln.Close()
     85 	err = cc.Control(fn)
     86 	if err == nil {
     87 		t.Fatal("Control after Close should fail")
     88 	}
     89 }
     90