net: test and fix support for 0-length datagram packets.

Fixes #274.

R=r
CC=jonathan.r.hudson
https://golang.org/cl/163072
This commit is contained in:
Russ Cox 2009-12-02 15:17:49 -08:00
parent acf4dd4d56
commit e89441ba8f
2 changed files with 39 additions and 25 deletions

View 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

View 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)
}
}
}