]> Cypherpunks repositories - gostls13.git/commitdiff
net: use original raddr if getpeername fails
authorMikio Hara <mikioh.mikioh@gmail.com>
Sat, 23 Mar 2013 13:32:19 +0000 (22:32 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Sat, 23 Mar 2013 13:32:19 +0000 (22:32 +0900)
This CL updates CL 7511043;
- adds new test cases for both UDPConn and UnixConn,
- makes sure unnamed UnixAddr handling,
- replaces t.Errorf with t.Fatalf in sockname related test cases.

Fixes #3721 (again).
Fixes #3838 (again).

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7627048

src/pkg/net/server_test.go
src/pkg/net/sock_posix.go
src/pkg/net/tcp_test.go
src/pkg/net/udp_test.go
src/pkg/net/unix_test.go
src/pkg/net/unixsock_posix.go

index c101ffecd1f35352044856cce1e24bdbb9fabfd6..9194a8ec24dd077fcd7b7defa15e78970528f594 100644 (file)
@@ -402,7 +402,7 @@ func runDatagramConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool)
                        t.Fatalf("Dial(%q, %q) failed: %v", net, taddr, err)
                }
        case "unixgram":
-               c, err = DialUnix(net, &UnixAddr{laddr, net}, &UnixAddr{taddr, net})
+               c, err = DialUnix(net, &UnixAddr{Name: laddr, Net: net}, &UnixAddr{Name: taddr, Net: net})
                if err != nil {
                        t.Fatalf("DialUnix(%q, {%q, %q}) failed: %v", net, laddr, taddr, err)
                }
index 2ebde87998142238dcae517bec4a0d1e951899e0..c8a94f50473a4ea24543c0351c4946cef07cfffa 100644 (file)
@@ -65,10 +65,10 @@ func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr,
        lsa, _ := syscall.Getsockname(s)
        laddr := toAddr(lsa)
        rsa, _ := syscall.Getpeername(s)
+       if rsa == nil {
+               rsa = ursa
+       }
        raddr := toAddr(rsa)
        fd.setAddr(laddr, raddr)
-       if fd.raddr == nil {
-               fd.raddr = toAddr(ursa)
-       }
        return fd, nil
 }
index add8e48234ceba292bece07e352689d42f84d135..b89202f50610914012c4b7b8a2a43d27fc36b5ff 100644 (file)
@@ -217,14 +217,12 @@ func TestTCPListenerName(t *testing.T) {
        for _, tt := range tcpListenerNameTests {
                ln, err := ListenTCP(tt.net, tt.laddr)
                if err != nil {
-                       t.Errorf("ListenTCP failed: %v", err)
-                       return
+                       t.Fatalf("ListenTCP failed: %v", err)
                }
                defer ln.Close()
                la := ln.Addr()
                if a, ok := la.(*TCPAddr); !ok || a.Port == 0 {
-                       t.Errorf("got %v; expected a proper address with non-zero port number", la)
-                       return
+                       t.Fatalf("got %v; expected a proper address with non-zero port number", la)
                }
        }
 }
index b3cafb096f488a8965433a40ef44f15b97d063aa..7a64c19ff29237b95569ca8142e767b4d2ad8cb3 100644 (file)
@@ -159,14 +159,50 @@ func TestUDPConnLocalName(t *testing.T) {
        for _, tt := range udpConnLocalNameTests {
                c, err := ListenUDP(tt.net, tt.laddr)
                if err != nil {
-                       t.Errorf("ListenUDP failed: %v", err)
-                       return
+                       t.Fatalf("ListenUDP failed: %v", err)
                }
                defer c.Close()
                la := c.LocalAddr()
                if a, ok := la.(*UDPAddr); !ok || a.Port == 0 {
-                       t.Errorf("got %v; expected a proper address with non-zero port number", la)
-                       return
+                       t.Fatalf("got %v; expected a proper address with non-zero port number", la)
+               }
+       }
+}
+
+func TestUDPConnLocalAndRemoteNames(t *testing.T) {
+       for _, laddr := range []string{"", "127.0.0.1:0"} {
+               c1, err := ListenPacket("udp", "127.0.0.1:0")
+               if err != nil {
+                       t.Fatalf("ListenUDP failed: %v", err)
+               }
+               defer c1.Close()
+
+               var la *UDPAddr
+               if laddr != "" {
+                       var err error
+                       if la, err = ResolveUDPAddr("udp", laddr); err != nil {
+                               t.Fatalf("ResolveUDPAddr failed: %v", err)
+                       }
+               }
+               c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr))
+               if err != nil {
+                       t.Fatalf("DialUDP failed: %v", err)
+               }
+               defer c2.Close()
+
+               var connAddrs = [4]struct {
+                       got Addr
+                       ok  bool
+               }{
+                       {c1.LocalAddr(), true},
+                       {c1.(*UDPConn).RemoteAddr(), false},
+                       {c2.LocalAddr(), true},
+                       {c2.RemoteAddr(), true},
+               }
+               for _, ca := range connAddrs {
+                       if a, ok := ca.got.(*UDPAddr); ok != ca.ok || ok && a.Port == 0 {
+                               t.Fatalf("got %v; expected a proper address with non-zero port number", ca.got)
+                       }
                }
        }
 }
index 2eaabe86e45eb7dfe4701fa586852d666661bce2..5e63e9d9decacc2ac9971c03f2ee16814bde0a09 100644 (file)
@@ -33,7 +33,6 @@ func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
 
        off := make(chan bool)
        data := [5]byte{1, 2, 3, 4, 5}
-
        go func() {
                defer func() { off <- true }()
                s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
@@ -54,15 +53,13 @@ func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
        c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
        n, from, err := c.ReadFrom(b)
        if err != nil {
-               t.Errorf("UnixConn.ReadFrom failed: %v", err)
-               return
+               t.Fatalf("UnixConn.ReadFrom failed: %v", err)
        }
        if from != nil {
-               t.Errorf("neighbor address is %v", from)
+               t.Fatalf("neighbor address is %v", from)
        }
        if !bytes.Equal(b[:n], data[:]) {
-               t.Errorf("got %v, want %v", b[:n], data[:])
-               return
+               t.Fatalf("got %v, want %v", b[:n], data[:])
        }
 }
 
@@ -101,13 +98,12 @@ func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) {
 
        <-off
        c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-       var peer Addr
-       if _, peer, err = c.ReadFrom(nil); err != nil {
-               t.Errorf("UnixConn.ReadFrom failed: %v", err)
-               return
+       _, from, err := c.ReadFrom(nil)
+       if err != nil {
+               t.Fatalf("UnixConn.ReadFrom failed: %v", err)
        }
-       if peer != nil {
-               t.Errorf("peer adddress is %v", peer)
+       if from != nil {
+               t.Fatalf("neighbor address is %v", from)
        }
 }
 
@@ -126,10 +122,10 @@ func TestUnixAutobind(t *testing.T) {
        // retrieve the autobind address
        autoAddr := c1.LocalAddr().(*UnixAddr)
        if len(autoAddr.Name) <= 1 {
-               t.Fatalf("Invalid autobind address: %v", autoAddr)
+               t.Fatalf("invalid autobind address: %v", autoAddr)
        }
        if autoAddr.Name[0] != '@' {
-               t.Fatalf("Invalid autobind address: %v", autoAddr)
+               t.Fatalf("invalid autobind address: %v", autoAddr)
        }
 
        c2, err := DialUnix("unixgram", nil, autoAddr)
@@ -139,6 +135,112 @@ func TestUnixAutobind(t *testing.T) {
        defer c2.Close()
 
        if !reflect.DeepEqual(c1.LocalAddr(), c2.RemoteAddr()) {
-               t.Fatalf("Expected autobind address %v, got %v", c1.LocalAddr(), c2.RemoteAddr())
+               t.Fatalf("expected autobind address %v, got %v", c1.LocalAddr(), c2.RemoteAddr())
+       }
+}
+
+func TestUnixConnLocalAndRemoteNames(t *testing.T) {
+       for _, laddr := range []string{"", testUnixAddr()} {
+               taddr := testUnixAddr()
+               ta, err := ResolveUnixAddr("unix", taddr)
+               if err != nil {
+                       t.Fatalf("ResolveUnixAddr failed: %v", err)
+               }
+               ln, err := ListenUnix("unix", ta)
+               if err != nil {
+                       t.Fatalf("ListenUnix failed: %v", err)
+               }
+               defer func() {
+                       ln.Close()
+                       os.Remove(taddr)
+               }()
+
+               done := make(chan int)
+               go transponder(t, ln, done)
+
+               la, err := ResolveUnixAddr("unix", laddr)
+               if err != nil {
+                       t.Fatalf("ResolveUnixAddr failed: %v", err)
+               }
+               c, err := DialUnix("unix", la, ta)
+               if err != nil {
+                       t.Fatalf("DialUnix failed: %v", err)
+               }
+               defer func() {
+                       c.Close()
+                       if la != nil {
+                               defer os.Remove(laddr)
+                       }
+               }()
+               if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
+                       t.Fatalf("UnixConn.Write failed: %v", err)
+               }
+
+               if runtime.GOOS == "linux" && laddr == "" {
+                       laddr = "@" // autobind feature
+               }
+               var connAddrs = [3]struct{ got, want Addr }{
+                       {ln.Addr(), ta},
+                       {c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}},
+                       {c.RemoteAddr(), ta},
+               }
+               for _, ca := range connAddrs {
+                       if !reflect.DeepEqual(ca.got, ca.want) {
+                               t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
+                       }
+               }
+
+               <-done
+       }
+}
+
+func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
+       for _, laddr := range []string{"", testUnixAddr()} {
+               taddr := testUnixAddr()
+               ta, err := ResolveUnixAddr("unixgram", taddr)
+               if err != nil {
+                       t.Fatalf("ResolveUnixAddr failed: %v", err)
+               }
+               c1, err := ListenUnixgram("unixgram", ta)
+               if err != nil {
+                       t.Fatalf("ListenUnixgram failed: %v", err)
+               }
+               defer func() {
+                       c1.Close()
+                       os.Remove(taddr)
+               }()
+
+               var la *UnixAddr
+               if laddr != "" {
+                       var err error
+                       if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
+                               t.Fatalf("ResolveUnixAddr failed: %v", err)
+                       }
+               }
+               c2, err := DialUnix("unixgram", la, ta)
+               if err != nil {
+                       t.Fatalf("DialUnix failed: %v", err)
+               }
+               defer func() {
+                       c2.Close()
+                       if la != nil {
+                               defer os.Remove(laddr)
+                       }
+               }()
+
+               if runtime.GOOS == "linux" && laddr == "" {
+                       laddr = "@" // autobind feature
+               }
+               var connAddrs = [4]struct{ got, want Addr }{
+                       {c1.LocalAddr(), ta},
+                       {c1.RemoteAddr(), nil},
+                       {c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}},
+                       {c2.RemoteAddr(), ta},
+               }
+               for _, ca := range connAddrs {
+                       if !reflect.DeepEqual(ca.got, ca.want) {
+                               t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
+                       }
+               }
        }
 }
index 8d57dacbd60cb15f9e8ee738da36cd481821ca0c..abdff09a8ac20e5e5d8c8ce12d2c184f0bbf4d31 100644 (file)
@@ -15,6 +15,13 @@ import (
        "time"
 )
 
+func (a *UnixAddr) isUnnamed() bool {
+       if a == nil || a.Name == "" {
+               return true
+       }
+       return false
+}
+
 func unixSocket(net string, laddr, raddr *UnixAddr, mode string, deadline time.Time) (*netFD, error) {
        var sotype int
        switch net {
@@ -31,12 +38,12 @@ func unixSocket(net string, laddr, raddr *UnixAddr, mode string, deadline time.T
        var la, ra syscall.Sockaddr
        switch mode {
        case "dial":
-               if laddr != nil {
+               if !laddr.isUnnamed() {
                        la = &syscall.SockaddrUnix{Name: laddr.Name}
                }
                if raddr != nil {
                        ra = &syscall.SockaddrUnix{Name: raddr.Name}
-               } else if sotype != syscall.SOCK_DGRAM || laddr == nil {
+               } else if sotype != syscall.SOCK_DGRAM || laddr.isUnnamed() {
                        return nil, &OpError{Op: mode, Net: net, Err: errMissingAddress}
                }
        case "listen":
@@ -69,21 +76,21 @@ error:
 
 func sockaddrToUnix(sa syscall.Sockaddr) Addr {
        if s, ok := sa.(*syscall.SockaddrUnix); ok {
-               return &UnixAddr{s.Name, "unix"}
+               return &UnixAddr{Name: s.Name, Net: "unix"}
        }
        return nil
 }
 
 func sockaddrToUnixgram(sa syscall.Sockaddr) Addr {
        if s, ok := sa.(*syscall.SockaddrUnix); ok {
-               return &UnixAddr{s.Name, "unixgram"}
+               return &UnixAddr{Name: s.Name, Net: "unixgram"}
        }
        return nil
 }
 
 func sockaddrToUnixpacket(sa syscall.Sockaddr) Addr {
        if s, ok := sa.(*syscall.SockaddrUnix); ok {
-               return &UnixAddr{s.Name, "unixpacket"}
+               return &UnixAddr{Name: s.Name, Net: "unixpacket"}
        }
        return nil
 }
@@ -92,10 +99,10 @@ func sotypeToNet(sotype int) string {
        switch sotype {
        case syscall.SOCK_STREAM:
                return "unix"
-       case syscall.SOCK_SEQPACKET:
-               return "unixpacket"
        case syscall.SOCK_DGRAM:
                return "unixgram"
+       case syscall.SOCK_SEQPACKET:
+               return "unixpacket"
        default:
                panic("sotypeToNet unknown socket type")
        }
@@ -124,7 +131,7 @@ func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err error) {
        switch sa := sa.(type) {
        case *syscall.SockaddrUnix:
                if sa.Name != "" {
-                       addr = &UnixAddr{sa.Name, sotypeToNet(c.fd.sotype)}
+                       addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
                }
        }
        return
@@ -151,7 +158,7 @@ func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAdd
        switch sa := sa.(type) {
        case *syscall.SockaddrUnix:
                if sa.Name != "" {
-                       addr = &UnixAddr{sa.Name, sotypeToNet(c.fd.sotype)}
+                       addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
                }
        }
        return