github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/src/net/unixsock_test.go (about)

     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  // +build !nacl,!plan9,!windows
     6  
     7  package net
     8  
     9  import (
    10  	"bytes"
    11  	"internal/testenv"
    12  	"io/ioutil"
    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 nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   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 nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   167  				t.Fatal(err)
   168  			}
   169  		}
   170  	}
   171  }
   172  
   173  func TestUnixgramAutobind(t *testing.T) {
   174  	if runtime.GOOS != "linux" {
   175  		t.Skip("autobind is linux only")
   176  	}
   177  
   178  	laddr := &UnixAddr{Name: "", Net: "unixgram"}
   179  	c1, err := ListenUnixgram("unixgram", laddr)
   180  	if err != nil {
   181  		t.Fatal(err)
   182  	}
   183  	defer c1.Close()
   184  
   185  	// retrieve the autobind address
   186  	autoAddr := c1.LocalAddr().(*UnixAddr)
   187  	if len(autoAddr.Name) <= 1 {
   188  		t.Fatalf("invalid autobind address: %v", autoAddr)
   189  	}
   190  	if autoAddr.Name[0] != '@' {
   191  		t.Fatalf("invalid autobind address: %v", autoAddr)
   192  	}
   193  
   194  	c2, err := DialUnix("unixgram", nil, autoAddr)
   195  	if err != nil {
   196  		t.Fatal(err)
   197  	}
   198  	defer c2.Close()
   199  
   200  	if !reflect.DeepEqual(c1.LocalAddr(), c2.RemoteAddr()) {
   201  		t.Fatalf("expected autobind address %v, got %v", c1.LocalAddr(), c2.RemoteAddr())
   202  	}
   203  }
   204  
   205  func TestUnixAutobindClose(t *testing.T) {
   206  	if runtime.GOOS != "linux" {
   207  		t.Skip("autobind is linux only")
   208  	}
   209  
   210  	laddr := &UnixAddr{Name: "", Net: "unix"}
   211  	ln, err := ListenUnix("unix", laddr)
   212  	if err != nil {
   213  		t.Fatal(err)
   214  	}
   215  	ln.Close()
   216  }
   217  
   218  func TestUnixgramWrite(t *testing.T) {
   219  	if !testableNetwork("unixgram") {
   220  		t.Skip("unixgram test")
   221  	}
   222  
   223  	addr := testUnixAddr()
   224  	laddr, err := ResolveUnixAddr("unixgram", addr)
   225  	if err != nil {
   226  		t.Fatal(err)
   227  	}
   228  	c, err := ListenPacket("unixgram", addr)
   229  	if err != nil {
   230  		t.Fatal(err)
   231  	}
   232  	defer os.Remove(addr)
   233  	defer c.Close()
   234  
   235  	testUnixgramWriteConn(t, laddr)
   236  	testUnixgramWritePacketConn(t, laddr)
   237  }
   238  
   239  func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) {
   240  	c, err := Dial("unixgram", raddr.String())
   241  	if err != nil {
   242  		t.Fatal(err)
   243  	}
   244  	defer c.Close()
   245  
   246  	b := []byte("CONNECTED-MODE SOCKET")
   247  	if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err == nil {
   248  		t.Fatal("should fail")
   249  	} else if err.(*OpError).Err != ErrWriteToConnected {
   250  		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
   251  	}
   252  	if _, err = c.(*UnixConn).WriteTo(b, raddr); err == nil {
   253  		t.Fatal("should fail")
   254  	} else if err.(*OpError).Err != ErrWriteToConnected {
   255  		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
   256  	}
   257  	if _, _, err = c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err == nil {
   258  		t.Fatal("should fail")
   259  	} else if err.(*OpError).Err != ErrWriteToConnected {
   260  		t.Fatalf("should fail as ErrWriteToConnected: %v", err)
   261  	}
   262  	if _, err := c.Write(b); err != nil {
   263  		t.Fatal(err)
   264  	}
   265  }
   266  
   267  func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) {
   268  	addr := testUnixAddr()
   269  	c, err := ListenPacket("unixgram", addr)
   270  	if err != nil {
   271  		t.Fatal(err)
   272  	}
   273  	defer os.Remove(addr)
   274  	defer c.Close()
   275  
   276  	b := []byte("UNCONNECTED-MODE SOCKET")
   277  	if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err != nil {
   278  		t.Fatal(err)
   279  	}
   280  	if _, err := c.WriteTo(b, raddr); err != nil {
   281  		t.Fatal(err)
   282  	}
   283  	if _, _, err := c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err != nil {
   284  		t.Fatal(err)
   285  	}
   286  	if _, err := c.(*UnixConn).Write(b); err == nil {
   287  		t.Fatal("should fail")
   288  	}
   289  }
   290  
   291  func TestUnixConnLocalAndRemoteNames(t *testing.T) {
   292  	if !testableNetwork("unix") {
   293  		t.Skip("unix test")
   294  	}
   295  
   296  	handler := func(ls *localServer, ln Listener) {}
   297  	for _, laddr := range []string{"", testUnixAddr()} {
   298  		laddr := laddr
   299  		taddr := testUnixAddr()
   300  		ta, err := ResolveUnixAddr("unix", taddr)
   301  		if err != nil {
   302  			t.Fatal(err)
   303  		}
   304  		ln, err := ListenUnix("unix", ta)
   305  		if err != nil {
   306  			t.Fatal(err)
   307  		}
   308  		ls, err := (&streamListener{Listener: ln}).newLocalServer()
   309  		if err != nil {
   310  			t.Fatal(err)
   311  		}
   312  		defer ls.teardown()
   313  		if err := ls.buildup(handler); err != nil {
   314  			t.Fatal(err)
   315  		}
   316  
   317  		la, err := ResolveUnixAddr("unix", laddr)
   318  		if err != nil {
   319  			t.Fatal(err)
   320  		}
   321  		c, err := DialUnix("unix", la, ta)
   322  		if err != nil {
   323  			t.Fatal(err)
   324  		}
   325  		defer func() {
   326  			c.Close()
   327  			if la != nil {
   328  				defer os.Remove(laddr)
   329  			}
   330  		}()
   331  		if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
   332  			t.Fatal(err)
   333  		}
   334  
   335  		switch runtime.GOOS {
   336  		case "android", "linux":
   337  			if laddr == "" {
   338  				laddr = "@" // autobind feature
   339  			}
   340  		}
   341  		var connAddrs = [3]struct{ got, want Addr }{
   342  			{ln.Addr(), ta},
   343  			{c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}},
   344  			{c.RemoteAddr(), ta},
   345  		}
   346  		for _, ca := range connAddrs {
   347  			if !reflect.DeepEqual(ca.got, ca.want) {
   348  				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
   349  			}
   350  		}
   351  	}
   352  }
   353  
   354  func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
   355  	if !testableNetwork("unixgram") {
   356  		t.Skip("unixgram test")
   357  	}
   358  
   359  	for _, laddr := range []string{"", testUnixAddr()} {
   360  		laddr := laddr
   361  		taddr := testUnixAddr()
   362  		ta, err := ResolveUnixAddr("unixgram", taddr)
   363  		if err != nil {
   364  			t.Fatal(err)
   365  		}
   366  		c1, err := ListenUnixgram("unixgram", ta)
   367  		if err != nil {
   368  			t.Fatal(err)
   369  		}
   370  		defer func() {
   371  			c1.Close()
   372  			os.Remove(taddr)
   373  		}()
   374  
   375  		var la *UnixAddr
   376  		if laddr != "" {
   377  			if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
   378  				t.Fatal(err)
   379  			}
   380  		}
   381  		c2, err := DialUnix("unixgram", la, ta)
   382  		if err != nil {
   383  			t.Fatal(err)
   384  		}
   385  		defer func() {
   386  			c2.Close()
   387  			if la != nil {
   388  				defer os.Remove(laddr)
   389  			}
   390  		}()
   391  
   392  		switch runtime.GOOS {
   393  		case "android", "linux":
   394  			if laddr == "" {
   395  				laddr = "@" // autobind feature
   396  			}
   397  		}
   398  
   399  		var connAddrs = [4]struct{ got, want Addr }{
   400  			{c1.LocalAddr(), ta},
   401  			{c1.RemoteAddr(), nil},
   402  			{c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}},
   403  			{c2.RemoteAddr(), ta},
   404  		}
   405  		for _, ca := range connAddrs {
   406  			if !reflect.DeepEqual(ca.got, ca.want) {
   407  				t.Fatalf("got %#v; want %#v", ca.got, ca.want)
   408  			}
   409  		}
   410  	}
   411  }
   412  
   413  func TestUnixUnlink(t *testing.T) {
   414  	if !testableNetwork("unix") {
   415  		t.Skip("unix test")
   416  	}
   417  	name := testUnixAddr()
   418  
   419  	listen := func(t *testing.T) *UnixListener {
   420  		l, err := Listen("unix", name)
   421  		if err != nil {
   422  			t.Fatal(err)
   423  		}
   424  		return l.(*UnixListener)
   425  	}
   426  	checkExists := func(t *testing.T, desc string) {
   427  		if _, err := os.Stat(name); err != nil {
   428  			t.Fatalf("unix socket does not exist %s: %v", desc, err)
   429  		}
   430  	}
   431  	checkNotExists := func(t *testing.T, desc string) {
   432  		if _, err := os.Stat(name); err == nil {
   433  			t.Fatalf("unix socket does exist %s: %v", desc, err)
   434  		}
   435  	}
   436  
   437  	// Listener should remove on close.
   438  	t.Run("Listen", func(t *testing.T) {
   439  		l := listen(t)
   440  		checkExists(t, "after Listen")
   441  		l.Close()
   442  		checkNotExists(t, "after Listener close")
   443  	})
   444  
   445  	// FileListener should not.
   446  	t.Run("FileListener", func(t *testing.T) {
   447  		l := listen(t)
   448  		f, _ := l.File()
   449  		l1, _ := FileListener(f)
   450  		checkExists(t, "after FileListener")
   451  		f.Close()
   452  		checkExists(t, "after File close")
   453  		l1.Close()
   454  		checkExists(t, "after FileListener close")
   455  		l.Close()
   456  		checkNotExists(t, "after Listener close")
   457  	})
   458  
   459  	// Only first call to l.Close should remove.
   460  	t.Run("SecondClose", func(t *testing.T) {
   461  		l := listen(t)
   462  		checkExists(t, "after Listen")
   463  		l.Close()
   464  		checkNotExists(t, "after Listener close")
   465  		if err := ioutil.WriteFile(name, []byte("hello world"), 0666); err != nil {
   466  			t.Fatalf("cannot recreate socket file: %v", err)
   467  		}
   468  		checkExists(t, "after writing temp file")
   469  		l.Close()
   470  		checkExists(t, "after second Listener close")
   471  		os.Remove(name)
   472  	})
   473  
   474  	// SetUnlinkOnClose should do what it says.
   475  
   476  	t.Run("Listen/SetUnlinkOnClose(true)", func(t *testing.T) {
   477  		l := listen(t)
   478  		checkExists(t, "after Listen")
   479  		l.SetUnlinkOnClose(true)
   480  		l.Close()
   481  		checkNotExists(t, "after Listener close")
   482  	})
   483  
   484  	t.Run("Listen/SetUnlinkOnClose(false)", func(t *testing.T) {
   485  		l := listen(t)
   486  		checkExists(t, "after Listen")
   487  		l.SetUnlinkOnClose(false)
   488  		l.Close()
   489  		checkExists(t, "after Listener close")
   490  		os.Remove(name)
   491  	})
   492  
   493  	t.Run("FileListener/SetUnlinkOnClose(true)", func(t *testing.T) {
   494  		l := listen(t)
   495  		f, _ := l.File()
   496  		l1, _ := FileListener(f)
   497  		checkExists(t, "after FileListener")
   498  		l1.(*UnixListener).SetUnlinkOnClose(true)
   499  		f.Close()
   500  		checkExists(t, "after File close")
   501  		l1.Close()
   502  		checkNotExists(t, "after FileListener close")
   503  		l.Close()
   504  	})
   505  
   506  	t.Run("FileListener/SetUnlinkOnClose(false)", func(t *testing.T) {
   507  		l := listen(t)
   508  		f, _ := l.File()
   509  		l1, _ := FileListener(f)
   510  		checkExists(t, "after FileListener")
   511  		l1.(*UnixListener).SetUnlinkOnClose(false)
   512  		f.Close()
   513  		checkExists(t, "after File close")
   514  		l1.Close()
   515  		checkExists(t, "after FileListener close")
   516  		l.Close()
   517  	})
   518  }