)
var (
- // Do not test datagrams with empty payload by default.
- // It depends on each platform implementation whether generic
- // read, socket recv system calls return the result of zero
- // byte read.
- testDatagram = flag.Bool("datagram", false, "whether to test UDP and unixgram")
-
testDNSFlood = flag.Bool("dnsflood", false, "whether to test DNS query flooding")
testExternal = flag.Bool("external", true, "allow use of external networks during long test")
{snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local"},
}
-func TestDatagramPacketConnServer(t *testing.T) {
- if !*testDatagram {
- return
- }
-
- for _, tt := range datagramPacketConnServerTests {
- if !testableListenArgs(tt.snet, tt.saddr, tt.caddr) {
- t.Logf("skipping %s test", tt.snet+":"+tt.saddr+"->"+tt.caddr)
- continue
- }
-
- listening := make(chan string)
- done := make(chan int)
- switch tt.snet {
- case "unixgram":
- os.Remove(tt.saddr)
- os.Remove(tt.caddr)
- }
-
- go runDatagramPacketConnServer(t, tt.snet, tt.saddr, listening, done)
- taddr := <-listening // wait for server to start
-
- switch tt.cnet {
- case "udp", "udp4", "udp6":
- _, port, err := SplitHostPort(taddr)
- if err != nil {
- t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err)
- }
- taddr = JoinHostPort(tt.caddr, port)
- tt.caddr = JoinHostPort(tt.caddr, "0")
- }
- if tt.dial {
- runDatagramConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
- } else {
- runDatagramPacketConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
- }
- <-done // tell server to stop
- <-done // make sure server stopped
-
- switch tt.snet {
- case "unixgram":
- os.Remove(tt.saddr)
- os.Remove(tt.caddr)
- }
- }
-}
-
func runDatagramPacketConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) {
c, err := ListenPacket(net, laddr)
if err != nil {
}
}
}
+
+func TestUDPZeroBytePayload(t *testing.T) {
+ switch runtime.GOOS {
+ case "nacl", "plan9":
+ t.Skipf("not supported on %s", runtime.GOOS)
+ }
+
+ c, err := newLocalPacketListener("udp")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer c.Close()
+
+ for _, genericRead := range []bool{false, true} {
+ n, err := c.WriteTo(nil, c.LocalAddr())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if n != 0 {
+ t.Errorf("got %d; want 0", n)
+ }
+ c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+ var b [1]byte
+ if genericRead {
+ _, err = c.(Conn).Read(b[:])
+ } else {
+ _, _, err = c.ReadFrom(b[:])
+ }
+ switch err {
+ case nil: // ReadFrom succeeds
+ default: // Read may timeout, it depends on the platform
+ if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ t.Fatal(err)
+ }
+ }
+ }
+}
+
+func TestUDPZeroByteBuffer(t *testing.T) {
+ switch runtime.GOOS {
+ case "nacl", "plan9":
+ t.Skipf("not supported on %s", runtime.GOOS)
+ }
+
+ c, err := newLocalPacketListener("udp")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer c.Close()
+
+ b := []byte("UDP ZERO BYTE BUFFER")
+ for _, genericRead := range []bool{false, true} {
+ n, err := c.WriteTo(b, c.LocalAddr())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if n != len(b) {
+ t.Errorf("got %d; want %d", n, len(b))
+ }
+ c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+ if genericRead {
+ _, err = c.(Conn).Read(nil)
+ } else {
+ _, _, err = c.ReadFrom(nil)
+ }
+ switch err {
+ case nil: // ReadFrom succeeds
+ default: // Read may timeout, it depends on the platform
+ if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows retruns WSAEMSGSIZ
+ t.Fatal(err)
+ }
+ }
+ }
+}
}
}
-func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) {
+func TestUnixgramZeroBytePayload(t *testing.T) {
if !testableNetwork("unixgram") {
t.Skip("unixgram test")
}
- // issue 4352: Recvfrom failed with "address family not
- // supported by protocol family" if zero-length buffer provided
- addr := testUnixAddr()
- la, err := ResolveUnixAddr("unixgram", addr)
+ c1, err := newLocalPacketListener("unixgram")
if err != nil {
- t.Fatalf("ResolveUnixAddr failed: %v", err)
+ t.Fatal(err)
}
- c, err := ListenUnixgram("unixgram", la)
+ defer os.Remove(c1.LocalAddr().String())
+ defer c1.Close()
+
+ c2, err := Dial("unixgram", c1.LocalAddr().String())
if err != nil {
- t.Fatalf("ListenUnixgram failed: %v", err)
+ t.Fatal(err)
}
- defer func() {
- c.Close()
- os.Remove(addr)
- }()
+ defer os.Remove(c2.LocalAddr().String())
+ defer c2.Close()
- off := make(chan bool)
- go func() {
- defer func() { off <- true }()
- c, err := DialUnix("unixgram", nil, la)
+ for _, genericRead := range []bool{false, true} {
+ n, err := c2.Write(nil)
if err != nil {
- t.Errorf("DialUnix failed: %v", err)
- return
+ t.Fatal(err)
}
- defer c.Close()
- if _, err := c.Write([]byte{1, 2, 3, 4, 5}); err != nil {
- t.Errorf("UnixConn.Write failed: %v", err)
- return
+ if n != 0 {
+ t.Errorf("got %d; want 0", n)
}
- }()
+ c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+ var b [1]byte
+ var peer Addr
+ if genericRead {
+ _, err = c1.(Conn).Read(b[:])
+ } else {
+ _, peer, err = c1.ReadFrom(b[:])
+ }
+ switch err {
+ case nil: // ReadFrom succeeds
+ if peer != nil { // peer is connected-mode
+ t.Fatalf("unexpected peer address: %v", peer)
+ }
+ default: // Read may timeout, it depends on the platform
+ if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ t.Fatal(err)
+ }
+ }
+ }
+}
- <-off
- c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
- _, from, err := c.ReadFrom(nil)
+func TestUnixgramZeroByteBuffer(t *testing.T) {
+ if !testableNetwork("unixgram") {
+ t.Skip("unixgram test")
+ }
+ // issue 4352: Recvfrom failed with "address family not
+ // supported by protocol family" if zero-length buffer provided
+
+ c1, err := newLocalPacketListener("unixgram")
if err != nil {
- t.Fatalf("UnixConn.ReadFrom failed: %v", err)
+ t.Fatal(err)
}
- if from != nil {
- t.Fatalf("neighbor address is %v", from)
+ defer os.Remove(c1.LocalAddr().String())
+ defer c1.Close()
+
+ c2, err := Dial("unixgram", c1.LocalAddr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.Remove(c2.LocalAddr().String())
+ defer c2.Close()
+
+ b := []byte("UNIXGRAM ZERO BYTE BUFFER")
+ for _, genericRead := range []bool{false, true} {
+ n, err := c2.Write(b)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if n != len(b) {
+ t.Errorf("got %d; want %d", n, len(b))
+ }
+ c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+ var peer Addr
+ if genericRead {
+ _, err = c1.(Conn).Read(nil)
+ } else {
+ _, peer, err = c1.ReadFrom(nil)
+ }
+ switch err {
+ case nil: // ReadFrom succeeds
+ if peer != nil { // peer is connected-mode
+ t.Fatalf("unexpected peer address: %v", peer)
+ }
+ default: // Read may timeout, it depends on the platform
+ if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ t.Fatal(err)
+ }
+ }
}
}