The Go linker isn't smart enough to prevent gvisor from being pulled
into modules that use other parts of tun/, due to the types exposed. So,
we put this into its own standalone module.
We use this as an opportunity to introduce some example code as well.
I'm still not happy that this not only clutters this repo's go.sum, but
all the other projects that consume it, but it seems like making a new
module inside of this repo will lead to even greater confusion.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Type tcpip.Error is not an error.
I've filed https://github.com/google/gvisor/issues/5314
to fix this upstream.
Until that is fixed, use %v instead of %w,
to keep vet happy.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This allows people to initiate connections over WireGuard without any
underlying operating system support.
I'm not crazy about the trash it adds to go.sum, but the code this
actually adds to the binaries seems contained to the gvisor repo.
For the TCP/IP implementation, it uses gvisor. And it borrows some
internals from the Go standard library's resolver in order to bring Dial
and DialContext to tun_net, along with the LookupHost helper function.
This allows for things like HTTP2-over-TLS to work quite well:
package main
import (
"io"
"log"
"net"
"net/http"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
)
func main() {
tun, tnet, err := tun.CreateNetTUN([]net.IP{net.ParseIP("192.168.4.29")}, []net.IP{net.ParseIP("8.8.8.8"), net.ParseIP("8.8.4.4")}, 1420)
if err != nil {
log.Panic(err)
}
dev := device.NewDevice(tun, &device.Logger{log.Default(), log.Default(), log.Default()})
dev.IpcSet(`private_key=a8dac1d8a70a751f0f699fb14ba1cff7b79cf4fbd8f09f44c6e6a90d0369604f
public_key=25123c5dcd3328ff645e4f2a3fce0d754400d3887a0cb7c56f0267e20fbf3c5b
endpoint=163.172.161.0:12912
allowed_ip=0.0.0.0/0
`)
dev.Up()
client := http.Client{
Transport: &http.Transport{
DialContext: tnet.DialContext,
},
}
resp, err := client.Get("https://www.zx2c4.com/ip")
if err != nil {
log.Panic(err)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Panic(err)
}
log.Println(string(body))
}
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>