]> Cypherpunks repositories - gostls13.git/commitdiff
net: test and fix support for 0-length datagram packets.
authorRuss Cox <rsc@golang.org>
Wed, 2 Dec 2009 23:17:49 +0000 (15:17 -0800)
committerRuss Cox <rsc@golang.org>
Wed, 2 Dec 2009 23:17:49 +0000 (15:17 -0800)
Fixes #274.

R=r
CC=jonathan.r.hudson
https://golang.org/cl/163072

src/pkg/net/fd.go
src/pkg/net/server_test.go

index e1592eb2691f3faed858ae00474ad667e1715423..733f957e518d6be8e97314143a2e9397fca1e1de 100644 (file)
@@ -386,6 +386,10 @@ func (fd *netFD) Read(p []byte) (n int, err os.Error) {
                }
                break;
        }
+       if fd.proto == syscall.SOCK_DGRAM && err == os.EOF {
+               // 0 in datagram protocol just means 0-length packet
+               err = nil
+       }
        return;
 }
 
@@ -433,7 +437,9 @@ func (fd *netFD) Write(p []byte) (n int, err os.Error) {
        }
        err = nil;
        nn := 0;
-       for nn < len(p) {
+       first := true;  // force at least one Write, to send 0-length datagram packets
+       for nn < len(p) || first {
+               first = false;
                n, err = fd.sysfile.Write(p[nn:]);
                if n > 0 {
                        nn += n
index d5c2f182cba2cd4cec5528f7d1c51cd70a6ec877..454f1d711971bfdb2f47b72074bd07c8fbed648b 100644 (file)
@@ -45,7 +45,7 @@ func runServe(t *testing.T, network, addr string, listening chan<- string, done
        done <- 1;
 }
 
-func connect(t *testing.T, network, addr string) {
+func connect(t *testing.T, network, addr string, isEmpty bool) {
        var laddr string;
        if network == "unixgram" {
                laddr = addr + ".local"
@@ -54,18 +54,22 @@ func connect(t *testing.T, network, addr string) {
        if err != nil {
                t.Fatalf("net.Dial(%q, %q, %q) = _, %v", network, laddr, addr, err)
        }
+       fd.SetReadTimeout(10e6);        // 10ms
 
-       b := strings.Bytes("hello, world\n");
+       var b []byte;
+       if !isEmpty {
+               b = strings.Bytes("hello, world\n")
+       }
        var b1 [100]byte;
 
-       n, errno := fd.Write(b);
+       n, err := fd.Write(b);
        if n != len(b) {
-               t.Fatalf("fd.Write(%q) = %d, %v", b, n, errno)
+               t.Fatalf("fd.Write(%q) = %d, %v", b, n, err)
        }
 
-       n, errno = fd.Read(&b1);
-       if n != len(b) {
-               t.Fatalf("fd.Read() = %d, %v", n, errno)
+       n, err = fd.Read(&b1);
+       if n != len(b) || err != nil {
+               t.Fatalf("fd.Read() = %d, %v (want %d, nil)", n, err, len(b))
        }
        fd.Close();
 }
@@ -82,7 +86,7 @@ func doTest(t *testing.T, network, listenaddr, dialaddr string) {
        if network == "tcp" {
                dialaddr += addr[strings.LastIndex(addr, ":"):]
        }
-       connect(t, network, dialaddr);
+       connect(t, network, dialaddr, false);
        <-done; // make sure server stopped
 }
 
@@ -133,7 +137,7 @@ func runPacket(t *testing.T, network, addr string, listening chan<- string, done
        done <- 1;
 }
 
-func doTestPacket(t *testing.T, network, listenaddr, dialaddr string) {
+func doTestPacket(t *testing.T, network, listenaddr, dialaddr string, isEmpty bool) {
        t.Logf("TestPacket %s %s %s\n", network, listenaddr, dialaddr);
        listening := make(chan string);
        done := make(chan int);
@@ -145,29 +149,33 @@ func doTestPacket(t *testing.T, network, listenaddr, dialaddr string) {
        if network == "udp" {
                dialaddr += addr[strings.LastIndex(addr, ":"):]
        }
-       connect(t, network, dialaddr);
+       connect(t, network, dialaddr, isEmpty);
        <-done; // tell server to stop
        <-done; // wait for stop
 }
 
 func TestUDPServer(t *testing.T) {
-       doTestPacket(t, "udp", "0.0.0.0", "127.0.0.1");
-       doTestPacket(t, "udp", "", "127.0.0.1");
-       if kernelSupportsIPv6() {
-               doTestPacket(t, "udp", "[::]", "[::ffff:127.0.0.1]");
-               doTestPacket(t, "udp", "[::]", "127.0.0.1");
-               doTestPacket(t, "udp", "0.0.0.0", "[::ffff:127.0.0.1]");
+       for _, isEmpty := range []bool{false, true} {
+               doTestPacket(t, "udp", "0.0.0.0", "127.0.0.1", isEmpty);
+               doTestPacket(t, "udp", "", "127.0.0.1", isEmpty);
+               if kernelSupportsIPv6() {
+                       doTestPacket(t, "udp", "[::]", "[::ffff:127.0.0.1]", isEmpty);
+                       doTestPacket(t, "udp", "[::]", "127.0.0.1", isEmpty);
+                       doTestPacket(t, "udp", "0.0.0.0", "[::ffff:127.0.0.1]", isEmpty);
+               }
        }
 }
 
 func TestUnixDatagramServer(t *testing.T) {
-       os.Remove("/tmp/gotest1.net");
-       os.Remove("/tmp/gotest1.net.local");
-       doTestPacket(t, "unixgram", "/tmp/gotest1.net", "/tmp/gotest1.net");
-       os.Remove("/tmp/gotest1.net");
-       os.Remove("/tmp/gotest1.net.local");
-       if syscall.OS == "linux" {
-               // Test abstract unix domain socket, a Linux-ism
-               doTestPacket(t, "unixgram", "@gotest1/net", "@gotest1/net")
+       for _, isEmpty := range []bool{false, true} {
+               os.Remove("/tmp/gotest1.net");
+               os.Remove("/tmp/gotest1.net.local");
+               doTestPacket(t, "unixgram", "/tmp/gotest1.net", "/tmp/gotest1.net", isEmpty);
+               os.Remove("/tmp/gotest1.net");
+               os.Remove("/tmp/gotest1.net.local");
+               if syscall.OS == "linux" {
+                       // Test abstract unix domain socket, a Linux-ism
+                       doTestPacket(t, "unixgram", "@gotest1/net", "@gotest1/net", isEmpty)
+               }
        }
 }