net: test and fix support for 0-length datagram packets.
Fixes #274.
R=r
CC=jonathan.r.hudson
https://golang.org/cl/163072
diff --git a/src/pkg/net/fd.go b/src/pkg/net/fd.go
index e1592eb..733f957 100644
--- a/src/pkg/net/fd.go
+++ b/src/pkg/net/fd.go
@@ -386,6 +386,10 @@
}
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 @@
}
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
diff --git a/src/pkg/net/server_test.go b/src/pkg/net/server_test.go
index d5c2f18..454f1d7 100644
--- a/src/pkg/net/server_test.go
+++ b/src/pkg/net/server_test.go
@@ -45,7 +45,7 @@
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 @@
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 @@
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 @@
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 @@
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)
+ }
}
}