@@ -8,15 +8,12 @@ package device
88import (
99 "bufio"
1010 "bytes"
11- "encoding/binary"
12- "io"
1311 "net"
14- "os"
1512 "strings"
1613 "testing"
1714 "time"
1815
19- "golang.zx2c4.com/wireguard/tun"
16+ "golang.zx2c4.com/wireguard/tun/tuntest "
2017)
2118
2219func TestTwoDevicePing (t * testing.T ) {
@@ -29,7 +26,7 @@ protocol_version=1
2926replace_allowed_ips=true
3027allowed_ip=1.0.0.2/32
3128endpoint=127.0.0.1:53512`
32- tun1 := NewChannelTUN ()
29+ tun1 := tuntest . NewChannelTUN ()
3330 dev1 := NewDevice (tun1 .TUN (), NewLogger (LogLevelDebug , "dev1: " ))
3431 dev1 .Up ()
3532 defer dev1 .Close ()
@@ -45,7 +42,7 @@ protocol_version=1
4542replace_allowed_ips=true
4643allowed_ip=1.0.0.1/32
4744endpoint=127.0.0.1:53511`
48- tun2 := NewChannelTUN ()
45+ tun2 := tuntest . NewChannelTUN ()
4946 dev2 := NewDevice (tun2 .TUN (), NewLogger (LogLevelDebug , "dev2: " ))
5047 dev2 .Up ()
5148 defer dev2 .Close ()
@@ -54,7 +51,7 @@ endpoint=127.0.0.1:53511`
5451 }
5552
5653 t .Run ("ping 1.0.0.1" , func (t * testing.T ) {
57- msg2to1 := ping (net .ParseIP ("1.0.0.1" ), net .ParseIP ("1.0.0.2" ))
54+ msg2to1 := tuntest . Ping (net .ParseIP ("1.0.0.1" ), net .ParseIP ("1.0.0.2" ))
5855 tun2 .Outbound <- msg2to1
5956 select {
6057 case msgRecv := <- tun1 .Inbound :
@@ -67,7 +64,7 @@ endpoint=127.0.0.1:53511`
6764 })
6865
6966 t .Run ("ping 1.0.0.2" , func (t * testing.T ) {
70- msg1to2 := ping (net .ParseIP ("1.0.0.2" ), net .ParseIP ("1.0.0.1" ))
67+ msg1to2 := tuntest . Ping (net .ParseIP ("1.0.0.2" ), net .ParseIP ("1.0.0.1" ))
7168 tun1 .Outbound <- msg1to2
7269 select {
7370 case msgRecv := <- tun2 .Inbound :
@@ -80,139 +77,6 @@ endpoint=127.0.0.1:53511`
8077 })
8178}
8279
83- func ping (dst , src net.IP ) []byte {
84- localPort := uint16 (1337 )
85- seq := uint16 (0 )
86-
87- payload := make ([]byte , 4 )
88- binary .BigEndian .PutUint16 (payload [0 :], localPort )
89- binary .BigEndian .PutUint16 (payload [2 :], seq )
90-
91- return genICMPv4 (payload , dst , src )
92- }
93-
94- // checksum is the "internet checksum" from https://tools.ietf.org/html/rfc1071.
95- func checksum (buf []byte , initial uint16 ) uint16 {
96- v := uint32 (initial )
97- for i := 0 ; i < len (buf )- 1 ; i += 2 {
98- v += uint32 (binary .BigEndian .Uint16 (buf [i :]))
99- }
100- if len (buf )% 2 == 1 {
101- v += uint32 (buf [len (buf )- 1 ]) << 8
102- }
103- for v > 0xffff {
104- v = (v >> 16 ) + (v & 0xffff )
105- }
106- return ^ uint16 (v )
107- }
108-
109- func genICMPv4 (payload []byte , dst , src net.IP ) []byte {
110- const (
111- icmpv4ProtocolNumber = 1
112- icmpv4Echo = 8
113- icmpv4ChecksumOffset = 2
114- icmpv4Size = 8
115- ipv4Size = 20
116- ipv4TotalLenOffset = 2
117- ipv4ChecksumOffset = 10
118- ttl = 65
119- )
120-
121- hdr := make ([]byte , ipv4Size + icmpv4Size )
122-
123- ip := hdr [0 :ipv4Size ]
124- icmpv4 := hdr [ipv4Size : ipv4Size + icmpv4Size ]
125-
126- // https://tools.ietf.org/html/rfc792
127- icmpv4 [0 ] = icmpv4Echo // type
128- icmpv4 [1 ] = 0 // code
129- chksum := ^ checksum (icmpv4 , checksum (payload , 0 ))
130- binary .BigEndian .PutUint16 (icmpv4 [icmpv4ChecksumOffset :], chksum )
131-
132- // https://tools.ietf.org/html/rfc760 section 3.1
133- length := uint16 (len (hdr ) + len (payload ))
134- ip [0 ] = (4 << 4 ) | (ipv4Size / 4 )
135- binary .BigEndian .PutUint16 (ip [ipv4TotalLenOffset :], length )
136- ip [8 ] = ttl
137- ip [9 ] = icmpv4ProtocolNumber
138- copy (ip [12 :], src .To4 ())
139- copy (ip [16 :], dst .To4 ())
140- chksum = ^ checksum (ip [:], 0 )
141- binary .BigEndian .PutUint16 (ip [ipv4ChecksumOffset :], chksum )
142-
143- var v []byte
144- v = append (v , hdr ... )
145- v = append (v , payload ... )
146- return []byte (v )
147- }
148-
149- // TODO(crawshaw): find a reusable home for this. package devicetest?
150- type ChannelTUN struct {
151- Inbound chan []byte // incoming packets, closed on TUN close
152- Outbound chan []byte // outbound packets, blocks forever on TUN close
153-
154- closed chan struct {}
155- events chan tun.Event
156- tun chTun
157- }
158-
159- func NewChannelTUN () * ChannelTUN {
160- c := & ChannelTUN {
161- Inbound : make (chan []byte ),
162- Outbound : make (chan []byte ),
163- closed : make (chan struct {}),
164- events : make (chan tun.Event , 1 ),
165- }
166- c .tun .c = c
167- c .events <- tun .EventUp
168- return c
169- }
170-
171- func (c * ChannelTUN ) TUN () tun.Device {
172- return & c .tun
173- }
174-
175- type chTun struct {
176- c * ChannelTUN
177- }
178-
179- func (t * chTun ) File () * os.File { return nil }
180-
181- func (t * chTun ) Read (data []byte , offset int ) (int , error ) {
182- select {
183- case <- t .c .closed :
184- return 0 , io .EOF // TODO(crawshaw): what is the correct error value?
185- case msg := <- t .c .Outbound :
186- return copy (data [offset :], msg ), nil
187- }
188- }
189-
190- // Write is called by the wireguard device to deliver a packet for routing.
191- func (t * chTun ) Write (data []byte , offset int ) (int , error ) {
192- if offset == - 1 {
193- close (t .c .closed )
194- close (t .c .events )
195- return 0 , io .EOF
196- }
197- msg := make ([]byte , len (data )- offset )
198- copy (msg , data [offset :])
199- select {
200- case <- t .c .closed :
201- return 0 , io .EOF // TODO(crawshaw): what is the correct error value?
202- case t .c .Inbound <- msg :
203- return len (data ) - offset , nil
204- }
205- }
206-
207- func (t * chTun ) Flush () error { return nil }
208- func (t * chTun ) MTU () (int , error ) { return DefaultMTU , nil }
209- func (t * chTun ) Name () (string , error ) { return "loopbackTun1" , nil }
210- func (t * chTun ) Events () chan tun.Event { return t .c .events }
211- func (t * chTun ) Close () error {
212- t .Write (nil , - 1 )
213- return nil
214- }
215-
21680func assertNil (t * testing.T , err error ) {
21781 if err != nil {
21882 t .Fatal (err )
0 commit comments