Hi, not sure if this is the place to ask wireguard-go question, can someone help to explain why the read doesnot work but write is ok? thanks
package wireguard
import (
"fmt"
"syscall"
"unsafe"
"net/netip"
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
"golang.zx2c4.com/wireguard/tun/netstack"
)
func NewUDP(localAddr, remoteAddr, privateKey, publicKey string,
mtu, localPort, remotePort int) (tun.Device, error) {
tun, _, err := netstack.CreateNetTUN(
[]netip.Addr{netip.MustParseAddr(localAddr)},
[]netip.Addr{netip.MustParseAddr("8.8.8.8")},
mtu,
)
if err != nil {
return nil, err
}
dev := device.NewDevice(tun, conn.NewDefaultBind(),
device.NewLogger(device.LogLevelVerbose, fmt.Sprint(localPort, ">")))
err = dev.IpcSet(fmt.Sprintf(`private_key=%s
listen_port=%d
public_key=%s
allowed_ip=0.0.0.0/0
endpoint=127.0.0.1:%d
`, privateKey, localPort, publicKey, remotePort))
if err != nil {
return nil, err
}
err = dev.Up()
if err != nil {
return nil, err
}
return tun, nil
}
package wireguard
import (
"errors"
"fmt"
"net"
"testing"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
func TestUDP(t *testing.T) {
exit := make(chan struct{})
msgCh := make(chan string, 2)
errCh := make(chan error, 2)
localAddr := "127.0.0.1"
serverAddr := "192.168.4.29"
serverPort := 58120
clientAddr := "192.168.4.28"
clientPort := 58122
mtu := 1200
go func() {
var (
privateKey = "003ed5d73b55806c30de3f8a7bdab38af13539220533055e635690b8b87ad641"
publicKey = "f928d4f6c1b86c12f2562c10b07c555c5c57fd00f59e90c8d8d88767271cbf7c"
)
conn, err := NewUDP(serverAddr, clientAddr, privateKey, publicKey, mtu, serverPort, clientPort)
if err != nil {
errCh <- err
return
}
data, err := ConstructUDP(localAddr, serverPort, localAddr, clientPort, []byte("Hello UDP Client"))
if err != nil {
errCh <- err
return
}
time.Sleep(2 * time.Second)
for {
select {
case <-exit:
return
default:
}
fmt.Println("++++server++++0")
n, err := conn.Write(data, 0)
if err != nil {
errCh <- err
return
}
if n == 0 {
errCh <- errors.New("server write 0")
return
}
fmt.Println("++++server++++1++", n)
conn.Flush()
var buf [2048]byte
_, err = conn.Read(buf[0:], 0)
if err != nil {
errCh <- err
return
}
fmt.Println("++++server++++2")
msgCh <- fmt.Sprint("server> ", string(buf[0:]))
}
}()
go func() {
var (
privateKey = "087ec6e14bbed210e7215cdc73468dfa23f080a1bfb8665b2fd809bd99d28379"
publicKey = "c4c8e984c5322c8184c72265b92b250fdb63688705f504ba003c88f03393cf28"
)
conn, err := NewUDP(clientAddr, serverAddr, privateKey, publicKey, mtu, clientPort, serverPort)
if err != nil {
errCh <- err
return
}
data, err := ConstructUDP(localAddr, clientPort, localAddr, serverPort, []byte("Hello UDP Server"))
if err != nil {
errCh <- err
return
}
time.Sleep(2 * time.Second)
for {
select {
case <-exit:
return
default:
}
fmt.Println("++++client++++0")
n, err := conn.Write(data, 0)
if err != nil {
errCh <- err
return
}
if n == 0 {
errCh <- errors.New("client write 0")
return
}
fmt.Println("++++client++++1++", n)
conn.Flush()
var buf [2048]byte
_, err = conn.Read(buf[0:], 0)
if err != nil {
errCh <- err
return
}
fmt.Println("++++client++++2")
msgCh <- fmt.Sprint("client> ", string(buf[0:]))
time.Sleep(5 * time.Second)
close(exit)
}
}()
select {
case msg := <-msgCh:
t.Log(msg)
case err := <-errCh:
close(exit)
t.Fatal(err)
case <-exit:
}
}
func ConstructUDP(srcIP string, srcPort int, dstIP string, dstPort int, data []byte) ([]byte, error) {
sIP := net.ParseIP(srcIP)
if sIP == nil {
return nil, fmt.Errorf("non-ip target: %q", srcIP)
}
sIP = sIP.To4()
if sIP == nil {
return nil, fmt.Errorf("non-ipv4 target: %q", srcIP)
}
dIP := net.ParseIP(dstIP)
if dIP == nil {
return nil, fmt.Errorf("non-ip target: %q", dstIP)
}
dIP = dIP.To4()
if dIP == nil {
return nil, fmt.Errorf("non-ipv4 target: %q", dstIP)
}
ip := layers.IPv4{
SrcIP: sIP,
DstIP: dIP,
Version: 4,
TTL: 64,
Protocol: layers.IPProtocolTCP,
}
sport := layers.TCPPort(srcPort)
dport := layers.TCPPort(dstPort)
tcp := layers.TCP{
SrcPort: sport,
DstPort: dport,
Window: 1505,
Urgent: 0,
Seq: 11050,
Ack: 0,
}
opts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
}
tcp.SetNetworkLayerForChecksum(&ip)
tcpPayloadBuf := gopacket.NewSerializeBuffer()
payload := gopacket.Payload(data)
if err := gopacket.SerializeLayers(tcpPayloadBuf, opts, &tcp, payload); err != nil {
return nil, fmt.Errorf("failed to serialize: %v", err)
}
return tcpPayloadBuf.Bytes(), nil
}