blob: 23552ec62430f39072180eafe577f07461cbed75 [file] [log] [blame]
Mikio Harad2e5a122012-09-26 21:03:09 +09001// Copyright 2012 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 darwin freebsd linux netbsd openbsd
6
7package ipv4_test
8
9import (
10 "code.google.com/p/go.net/ipv4"
11 "net"
12 "os"
13 "testing"
14)
15
Mikio Harab073adc2013-06-16 16:58:31 +090016func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
17 c, err := net.ListenPacket("udp4", "127.0.0.1:0")
18 if err != nil {
19 return nil, nil, err
20 }
21 dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
22 if err != nil {
23 c.Close()
24 return nil, nil, err
25 }
26 return c, dst, nil
27}
28
29func BenchmarkReadWriteNetUDP(b *testing.B) {
30 c, dst, err := benchmarkUDPListener()
31 if err != nil {
32 b.Fatalf("benchmarkUDPListener failed: %v", err)
33 }
34 defer c.Close()
35
36 wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
37 b.ResetTimer()
38 for i := 0; i < b.N; i++ {
39 benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
40 }
41}
42
43func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
44 if _, err := c.WriteTo(wb, dst); err != nil {
45 b.Fatalf("net.PacketConn.WriteTo failed: %v", err)
46 }
47 if _, _, err := c.ReadFrom(rb); err != nil {
48 b.Fatalf("net.PacketConn.ReadFrom failed: %v", err)
49 }
50}
51
52func BenchmarkReadWriteIPv4UDP(b *testing.B) {
53 c, dst, err := benchmarkUDPListener()
54 if err != nil {
55 b.Fatalf("benchmarkUDPListener failed: %v", err)
56 }
57 defer c.Close()
58
59 p := ipv4.NewPacketConn(c)
60 cf := ipv4.FlagTTL | ipv4.FlagInterface
61 if err := p.SetControlMessage(cf, true); err != nil {
62 b.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err)
63 }
64 ifi := loopbackInterface()
65
66 wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
67 b.ResetTimer()
68 for i := 0; i < b.N; i++ {
69 benchmarkReadWriteIPv4UDP(b, p, wb, rb, dst, ifi)
70 }
71}
72
73func benchmarkReadWriteIPv4UDP(b *testing.B, p *ipv4.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
74 cm := ipv4.ControlMessage{TTL: 1}
75 if ifi != nil {
76 cm.IfIndex = ifi.Index
77 }
78 if _, err := p.WriteTo(wb, &cm, dst); err != nil {
79 b.Fatalf("ipv4.PacketConn.WriteTo failed: %v", err)
80 }
81 if _, _, _, err := p.ReadFrom(rb); err != nil {
82 b.Fatalf("ipv4.PacketConn.ReadFrom failed: %v", err)
83 }
84}
85
Mikio Harad2e5a122012-09-26 21:03:09 +090086func TestReadWriteUnicastIPPayloadUDP(t *testing.T) {
87 c, err := net.ListenPacket("udp4", "127.0.0.1:0")
88 if err != nil {
89 t.Fatalf("net.ListenPacket failed: %v", err)
90 }
91 defer c.Close()
92
93 dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
94 if err != nil {
95 t.Fatalf("net.ResolveUDPAddr failed: %v", err)
96 }
Mikio Harad2e5a122012-09-26 21:03:09 +090097 p := ipv4.NewPacketConn(c)
Mikio Hara6b91bf22013-02-16 13:02:07 +090098 cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
99 for i, toggle := range []bool{true, false, true} {
100 if err := p.SetControlMessage(cf, toggle); err != nil {
101 t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err)
102 }
103 writeThenReadPayload(t, i, p, []byte("HELLO-R-U-THERE"), dst)
104 }
Mikio Harad2e5a122012-09-26 21:03:09 +0900105}
106
107func TestReadWriteUnicastIPPayloadICMP(t *testing.T) {
108 if os.Getuid() != 0 {
Mikio Hara413497e2013-04-04 14:37:01 +0900109 t.Skip("must be root")
Mikio Harad2e5a122012-09-26 21:03:09 +0900110 }
111
112 c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
113 if err != nil {
114 t.Fatalf("net.ListenPacket failed: %v", err)
115 }
116 defer c.Close()
117
118 dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
119 if err != nil {
120 t.Fatalf("ResolveIPAddr failed: %v", err)
121 }
Mikio Harad2e5a122012-09-26 21:03:09 +0900122 p := ipv4.NewPacketConn(c)
Mikio Hara6b91bf22013-02-16 13:02:07 +0900123 cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
124 for i, toggle := range []bool{true, false, true} {
125 wb, err := (&icmpMessage{
Mikio Hara8108b4b2013-06-07 14:52:58 +0900126 Type: ipv4.ICMPTypeEcho, Code: 0,
Mikio Hara6b91bf22013-02-16 13:02:07 +0900127 Body: &icmpEcho{
128 ID: os.Getpid() & 0xffff, Seq: i + 1,
129 Data: []byte("HELLO-R-U-THERE"),
130 },
131 }).Marshal()
132 if err != nil {
133 t.Fatalf("icmpMessage.Marshal failed: %v", err)
134 }
135 if err := p.SetControlMessage(cf, toggle); err != nil {
136 t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err)
137 }
138 rb := writeThenReadPayload(t, i, p, wb, dst)
139 m, err := parseICMPMessage(rb)
140 if err != nil {
141 t.Fatalf("parseICMPMessage failed: %v", err)
142 }
Mikio Hara8108b4b2013-06-07 14:52:58 +0900143 if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
144 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
Mikio Hara6b91bf22013-02-16 13:02:07 +0900145 }
146 }
Mikio Harad2e5a122012-09-26 21:03:09 +0900147}
148
149func TestReadWriteUnicastIPDatagram(t *testing.T) {
150 if os.Getuid() != 0 {
Mikio Hara413497e2013-04-04 14:37:01 +0900151 t.Skip("must be root")
Mikio Harad2e5a122012-09-26 21:03:09 +0900152 }
153
154 c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
155 if err != nil {
156 t.Fatalf("net.ListenPacket failed: %v", err)
157 }
158 defer c.Close()
159
160 dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
161 if err != nil {
162 t.Fatalf("ResolveIPAddr failed: %v", err)
163 }
Mikio Harad2e5a122012-09-26 21:03:09 +0900164 r, err := ipv4.NewRawConn(c)
165 if err != nil {
166 t.Fatalf("ipv4.NewRawConn failed: %v", err)
167 }
Mikio Hara6b91bf22013-02-16 13:02:07 +0900168 cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
169 for i, toggle := range []bool{true, false, true} {
170 wb, err := (&icmpMessage{
Mikio Hara8108b4b2013-06-07 14:52:58 +0900171 Type: ipv4.ICMPTypeEcho, Code: 0,
Mikio Hara6b91bf22013-02-16 13:02:07 +0900172 Body: &icmpEcho{
173 ID: os.Getpid() & 0xffff, Seq: i + 1,
174 Data: []byte("HELLO-R-U-THERE"),
175 },
176 }).Marshal()
177 if err != nil {
178 t.Fatalf("icmpMessage.Marshal failed: %v", err)
179 }
180 if err := r.SetControlMessage(cf, toggle); err != nil {
181 t.Fatalf("ipv4.RawConn.SetControlMessage failed: %v", err)
182 }
183 rb := writeThenReadDatagram(t, i, r, wb, nil, dst)
184 m, err := parseICMPMessage(rb)
185 if err != nil {
186 t.Fatalf("parseICMPMessage failed: %v", err)
187 }
Mikio Hara8108b4b2013-06-07 14:52:58 +0900188 if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
189 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
Mikio Hara6b91bf22013-02-16 13:02:07 +0900190 }
191 }
Mikio Harad2e5a122012-09-26 21:03:09 +0900192}