...

Source file src/net/unixsock_test.go

Documentation: net

		 1  // Copyright 2013 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 && !plan9 && !windows
		 6  // +build !js,!plan9,!windows
		 7  
		 8  package net
		 9  
		10  import (
		11  	"bytes"
		12  	"internal/testenv"
		13  	"os"
		14  	"reflect"
		15  	"runtime"
		16  	"syscall"
		17  	"testing"
		18  	"time"
		19  )
		20  
		21  func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
		22  	if !testableNetwork("unixgram") {
		23  		t.Skip("unixgram test")
		24  	}
		25  	if runtime.GOOS == "openbsd" {
		26  		testenv.SkipFlaky(t, 15157)
		27  	}
		28  
		29  	addr := testUnixAddr()
		30  	la, err := ResolveUnixAddr("unixgram", addr)
		31  	if err != nil {
		32  		t.Fatal(err)
		33  	}
		34  	c, err := ListenUnixgram("unixgram", la)
		35  	if err != nil {
		36  		t.Fatal(err)
		37  	}
		38  	defer func() {
		39  		c.Close()
		40  		os.Remove(addr)
		41  	}()
		42  
		43  	off := make(chan bool)
		44  	data := [5]byte{1, 2, 3, 4, 5}
		45  	go func() {
		46  		defer func() { off <- true }()
		47  		s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
		48  		if err != nil {
		49  			t.Error(err)
		50  			return
		51  		}
		52  		defer syscall.Close(s)
		53  		rsa := &syscall.SockaddrUnix{Name: addr}
		54  		if err := syscall.Sendto(s, data[:], 0, rsa); err != nil {
		55  			t.Error(err)
		56  			return
		57  		}
		58  	}()
		59  
		60  	<-off
		61  	b := make([]byte, 64)
		62  	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
		63  	n, from, err := c.ReadFrom(b)
		64  	if err != nil {
		65  		t.Fatal(err)
		66  	}
		67  	if from != nil {
		68  		t.Fatalf("unexpected peer address: %v", from)
		69  	}
		70  	if !bytes.Equal(b[:n], data[:]) {
		71  		t.Fatalf("got %v; want %v", b[:n], data[:])
		72  	}
		73  }
		74  
		75  func TestUnixgramZeroBytePayload(t *testing.T) {
		76  	if !testableNetwork("unixgram") {
		77  		t.Skip("unixgram test")
		78  	}
		79  
		80  	c1, err := newLocalPacketListener("unixgram")
		81  	if err != nil {
		82  		t.Fatal(err)
		83  	}
		84  	defer os.Remove(c1.LocalAddr().String())
		85  	defer c1.Close()
		86  
		87  	c2, err := Dial("unixgram", c1.LocalAddr().String())
		88  	if err != nil {
		89  		t.Fatal(err)
		90  	}
		91  	defer os.Remove(c2.LocalAddr().String())
		92  	defer c2.Close()
		93  
		94  	for _, genericRead := range []bool{false, true} {
		95  		n, err := c2.Write(nil)
		96  		if err != nil {
		97  			t.Fatal(err)
		98  		}
		99  		if n != 0 {
	 100  			t.Errorf("got %d; want 0", n)
	 101  		}
	 102  		c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
	 103  		var b [1]byte
	 104  		var peer Addr
	 105  		if genericRead {
	 106  			_, err = c1.(Conn).Read(b[:])
	 107  		} else {
	 108  			_, peer, err = c1.ReadFrom(b[:])
	 109  		}
	 110  		switch err {
	 111  		case nil: // ReadFrom succeeds
	 112  			if peer != nil { // peer is connected-mode
	 113  				t.Fatalf("unexpected peer address: %v", peer)
	 114  			}
	 115  		default: // Read may timeout, it depends on the platform
	 116  			if !isDeadlineExceeded(err) {
	 117  				t.Fatal(err)
	 118  			}
	 119  		}
	 120  	}
	 121  }
	 122  
	 123  func TestUnixgramZeroByteBuffer(t *testing.T) {
	 124  	if !testableNetwork("unixgram") {
	 125  		t.Skip("unixgram test")
	 126  	}
	 127  	// issue 4352: Recvfrom failed with "address family not
	 128  	// supported by protocol family" if zero-length buffer provided
	 129  
	 130  	c1, err := newLocalPacketListener("unixgram")
	 131  	if err != nil {
	 132  		t.Fatal(err)
	 133  	}
	 134  	defer os.Remove(c1.LocalAddr().String())
	 135  	defer c1.Close()
	 136  
	 137  	c2, err := Dial("unixgram", c1.LocalAddr().String())
	 138  	if err != nil {
	 139  		t.Fatal(err)
	 140  	}
	 141  	defer os.Remove(c2.LocalAddr().String())
	 142  	defer c2.Close()
	 143  
	 144  	b := []byte("UNIXGRAM ZERO BYTE BUFFER TEST")
	 145  	for _, genericRead := range []bool{false, true} {
	 146  		n, err := c2.Write(b)
	 147  		if err != nil {
	 148  			t.Fatal(err)
	 149  		}
	 150  		if n != len(b) {
	 151  			t.Errorf("got %d; want %d", n, len(b))
	 152  		}
	 153  		c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
	 154  		var peer Addr
	 155  		if genericRead {
	 156  			_, err = c1.(Conn).Read(nil)
	 157  		} else {
	 158  			_, peer, err = c1.ReadFrom(nil)
	 159  		}
	 160  		switch err {
	 161  		case nil: // ReadFrom succeeds
	 162  			if peer != nil { // peer is connected-mode
	 163  				t.Fatalf("unexpected peer address: %v", peer)
	 164  			}
	 165  		default: // Read may timeout, it depends on the platform
	 166  			if !isDeadlineExceeded(err) {
	 167  				t.Fatal(err)
	 168  			}
	 169  		}
	 170  	}
	 171  }
	 172  
	 173  func TestUnixgramWrite(t *testing.T) {
	 174  	if !testableNetwork("unixgram") {
	 175  		t.Skip("unixgram test")
	 176  	}
	 177  
	 178  	addr := testUnixAddr()
	 179  	laddr, err := ResolveUnixAddr("unixgram", addr)
	 180  	if err != nil {
	 181  		t.Fatal(err)
	 182  	}
	 183  	c, err := ListenPacket("unixgram", addr)
	 184  	if err != nil {
	 185  		t.Fatal(err)
	 186  	}
	 187  	defer os.Remove(addr)
	 188  	defer c.Close()
	 189  
	 190  	testUnixgramWriteConn(t, laddr)
	 191  	testUnixgramWritePacketConn(t, laddr)
	 192  }
	 193  
	 194  func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) {
	 195  	c, err := Dial("unixgram", raddr.String())
	 196  	if err != nil {
	 197  		t.Fatal(err)
	 198  	}
	 199  	defer c.Close()
	 200  
	 201  	b := []byte("CONNECTED-MODE SOCKET")
	 202  	if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err == nil {
	 203  		t.Fatal("should fail")
	 204  	} else if err.(*OpError).Err != ErrWriteToConnected {
	 205  		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
	 206  	}
	 207  	if _, err = c.(*UnixConn).WriteTo(b, raddr); err == nil {
	 208  		t.Fatal("should fail")
	 209  	} else if err.(*OpError).Err != ErrWriteToConnected {
	 210  		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
	 211  	}
	 212  	if _, _, err = c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err == nil {
	 213  		t.Fatal("should fail")
	 214  	} else if err.(*OpError).Err != ErrWriteToConnected {
	 215  		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
	 216  	}
	 217  	if _, err := c.Write(b); err != nil {
	 218  		t.Fatal(err)
	 219  	}
	 220  }
	 221  
	 222  func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) {
	 223  	addr := testUnixAddr()
	 224  	c, err := ListenPacket("unixgram", addr)
	 225  	if err != nil {
	 226  		t.Fatal(err)
	 227  	}
	 228  	defer os.Remove(addr)
	 229  	defer c.Close()
	 230  
	 231  	b := []byte("UNCONNECTED-MODE SOCKET")
	 232  	if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err != nil {
	 233  		t.Fatal(err)
	 234  	}
	 235  	if _, err := c.WriteTo(b, raddr); err != nil {
	 236  		t.Fatal(err)
	 237  	}
	 238  	if _, _, err := c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err != nil {
	 239  		t.Fatal(err)
	 240  	}
	 241  	if _, err := c.(*UnixConn).Write(b); err == nil {
	 242  		t.Fatal("should fail")
	 243  	}
	 244  }
	 245  
	 246  func TestUnixConnLocalAndRemoteNames(t *testing.T) {
	 247  	if !testableNetwork("unix") {
	 248  		t.Skip("unix test")
	 249  	}
	 250  
	 251  	handler := func(ls *localServer, ln Listener) {}
	 252  	for _, laddr := range []string{"", testUnixAddr()} {
	 253  		laddr := laddr
	 254  		taddr := testUnixAddr()
	 255  		ta, err := ResolveUnixAddr("unix", taddr)
	 256  		if err != nil {
	 257  			t.Fatal(err)
	 258  		}
	 259  		ln, err := ListenUnix("unix", ta)
	 260  		if err != nil {
	 261  			t.Fatal(err)
	 262  		}
	 263  		ls, err := (&streamListener{Listener: ln}).newLocalServer()
	 264  		if err != nil {
	 265  			t.Fatal(err)
	 266  		}
	 267  		defer ls.teardown()
	 268  		if err := ls.buildup(handler); err != nil {
	 269  			t.Fatal(err)
	 270  		}
	 271  
	 272  		la, err := ResolveUnixAddr("unix", laddr)
	 273  		if err != nil {
	 274  			t.Fatal(err)
	 275  		}
	 276  		c, err := DialUnix("unix", la, ta)
	 277  		if err != nil {
	 278  			t.Fatal(err)
	 279  		}
	 280  		defer func() {
	 281  			c.Close()
	 282  			if la != nil {
	 283  				defer os.Remove(laddr)
	 284  			}
	 285  		}()
	 286  		if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
	 287  			t.Fatal(err)
	 288  		}
	 289  
	 290  		switch runtime.GOOS {
	 291  		case "android", "linux":
	 292  			if laddr == "" {
	 293  				laddr = "@" // autobind feature
	 294  			}
	 295  		}
	 296  		var connAddrs = [3]struct{ got, want Addr }{
	 297  			{ln.Addr(), ta},
	 298  			{c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}},
	 299  			{c.RemoteAddr(), ta},
	 300  		}
	 301  		for _, ca := range connAddrs {
	 302  			if !reflect.DeepEqual(ca.got, ca.want) {
	 303  				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
	 304  			}
	 305  		}
	 306  	}
	 307  }
	 308  
	 309  func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
	 310  	if !testableNetwork("unixgram") {
	 311  		t.Skip("unixgram test")
	 312  	}
	 313  
	 314  	for _, laddr := range []string{"", testUnixAddr()} {
	 315  		laddr := laddr
	 316  		taddr := testUnixAddr()
	 317  		ta, err := ResolveUnixAddr("unixgram", taddr)
	 318  		if err != nil {
	 319  			t.Fatal(err)
	 320  		}
	 321  		c1, err := ListenUnixgram("unixgram", ta)
	 322  		if err != nil {
	 323  			t.Fatal(err)
	 324  		}
	 325  		defer func() {
	 326  			c1.Close()
	 327  			os.Remove(taddr)
	 328  		}()
	 329  
	 330  		var la *UnixAddr
	 331  		if laddr != "" {
	 332  			if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
	 333  				t.Fatal(err)
	 334  			}
	 335  		}
	 336  		c2, err := DialUnix("unixgram", la, ta)
	 337  		if err != nil {
	 338  			t.Fatal(err)
	 339  		}
	 340  		defer func() {
	 341  			c2.Close()
	 342  			if la != nil {
	 343  				defer os.Remove(laddr)
	 344  			}
	 345  		}()
	 346  
	 347  		switch runtime.GOOS {
	 348  		case "android", "linux":
	 349  			if laddr == "" {
	 350  				laddr = "@" // autobind feature
	 351  			}
	 352  		}
	 353  
	 354  		var connAddrs = [4]struct{ got, want Addr }{
	 355  			{c1.LocalAddr(), ta},
	 356  			{c1.RemoteAddr(), nil},
	 357  			{c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}},
	 358  			{c2.RemoteAddr(), ta},
	 359  		}
	 360  		for _, ca := range connAddrs {
	 361  			if !reflect.DeepEqual(ca.got, ca.want) {
	 362  				t.Fatalf("got %#v; want %#v", ca.got, ca.want)
	 363  			}
	 364  		}
	 365  	}
	 366  }
	 367  
	 368  func TestUnixUnlink(t *testing.T) {
	 369  	if !testableNetwork("unix") {
	 370  		t.Skip("unix test")
	 371  	}
	 372  	name := testUnixAddr()
	 373  
	 374  	listen := func(t *testing.T) *UnixListener {
	 375  		l, err := Listen("unix", name)
	 376  		if err != nil {
	 377  			t.Fatal(err)
	 378  		}
	 379  		return l.(*UnixListener)
	 380  	}
	 381  	checkExists := func(t *testing.T, desc string) {
	 382  		if _, err := os.Stat(name); err != nil {
	 383  			t.Fatalf("unix socket does not exist %s: %v", desc, err)
	 384  		}
	 385  	}
	 386  	checkNotExists := func(t *testing.T, desc string) {
	 387  		if _, err := os.Stat(name); err == nil {
	 388  			t.Fatalf("unix socket does exist %s: %v", desc, err)
	 389  		}
	 390  	}
	 391  
	 392  	// Listener should remove on close.
	 393  	t.Run("Listen", func(t *testing.T) {
	 394  		l := listen(t)
	 395  		checkExists(t, "after Listen")
	 396  		l.Close()
	 397  		checkNotExists(t, "after Listener close")
	 398  	})
	 399  
	 400  	// FileListener should not.
	 401  	t.Run("FileListener", func(t *testing.T) {
	 402  		l := listen(t)
	 403  		f, _ := l.File()
	 404  		l1, _ := FileListener(f)
	 405  		checkExists(t, "after FileListener")
	 406  		f.Close()
	 407  		checkExists(t, "after File close")
	 408  		l1.Close()
	 409  		checkExists(t, "after FileListener close")
	 410  		l.Close()
	 411  		checkNotExists(t, "after Listener close")
	 412  	})
	 413  
	 414  	// Only first call to l.Close should remove.
	 415  	t.Run("SecondClose", func(t *testing.T) {
	 416  		l := listen(t)
	 417  		checkExists(t, "after Listen")
	 418  		l.Close()
	 419  		checkNotExists(t, "after Listener close")
	 420  		if err := os.WriteFile(name, []byte("hello world"), 0666); err != nil {
	 421  			t.Fatalf("cannot recreate socket file: %v", err)
	 422  		}
	 423  		checkExists(t, "after writing temp file")
	 424  		l.Close()
	 425  		checkExists(t, "after second Listener close")
	 426  		os.Remove(name)
	 427  	})
	 428  
	 429  	// SetUnlinkOnClose should do what it says.
	 430  
	 431  	t.Run("Listen/SetUnlinkOnClose(true)", func(t *testing.T) {
	 432  		l := listen(t)
	 433  		checkExists(t, "after Listen")
	 434  		l.SetUnlinkOnClose(true)
	 435  		l.Close()
	 436  		checkNotExists(t, "after Listener close")
	 437  	})
	 438  
	 439  	t.Run("Listen/SetUnlinkOnClose(false)", func(t *testing.T) {
	 440  		l := listen(t)
	 441  		checkExists(t, "after Listen")
	 442  		l.SetUnlinkOnClose(false)
	 443  		l.Close()
	 444  		checkExists(t, "after Listener close")
	 445  		os.Remove(name)
	 446  	})
	 447  
	 448  	t.Run("FileListener/SetUnlinkOnClose(true)", func(t *testing.T) {
	 449  		l := listen(t)
	 450  		f, _ := l.File()
	 451  		l1, _ := FileListener(f)
	 452  		checkExists(t, "after FileListener")
	 453  		l1.(*UnixListener).SetUnlinkOnClose(true)
	 454  		f.Close()
	 455  		checkExists(t, "after File close")
	 456  		l1.Close()
	 457  		checkNotExists(t, "after FileListener close")
	 458  		l.Close()
	 459  	})
	 460  
	 461  	t.Run("FileListener/SetUnlinkOnClose(false)", func(t *testing.T) {
	 462  		l := listen(t)
	 463  		f, _ := l.File()
	 464  		l1, _ := FileListener(f)
	 465  		checkExists(t, "after FileListener")
	 466  		l1.(*UnixListener).SetUnlinkOnClose(false)
	 467  		f.Close()
	 468  		checkExists(t, "after File close")
	 469  		l1.Close()
	 470  		checkExists(t, "after FileListener close")
	 471  		l.Close()
	 472  	})
	 473  }
	 474  

View as plain text