i have written the following simple udp server/client in golang. The app sends the current time to a specified ipv6 link-local addrress. The receiver sends back a little reply. This works ONLY if the sender port of the reply is the same as the destination port of the request.
Wireshark Comparison: https://www.dropbox.com/s/ypaepz62sa4xtnh/go_simple_udp3.png?dl=0
Why is this the case?
package main
import (
"net"
"log"
"fmt"
"time"
)
func main() {
//Remote Addr
BoxAddr, err := net.ResolveUDPAddr("udp6", "[fe80:0000:0000:0000:0211:7d00:0030:8e3f]:5684")
if(err != nil) {
log.Fatal(err)
return
}
/*
LocalAddr, err := net.ResolveUDPAddr("udp6", "[fe80::299f:4146:2e32:72fd%4]:50361")
if(err != nil) {
log.Fatal(err)
return
}
*/
c, err := net.DialUDP("udp6", nil, BoxAddr)
if(err != nil) {
log.Fatal(err)
return
}
defer c.Close()
fmt.Print(c.LocalAddr())
//read loop
go func(c *net.UDPConn) {
for {
rxMsg := make([]byte, 100);
n,_, err := c.ReadFromUDP(rxMsg)
if(err != nil) {
log.Fatal(err)
return
} else {
fmt.Print("Got from remote: ",n, " bytes
")
}
}
}(c)
//write every second current time
for {
b := []byte(time.Now().String())
n, err := c.Write(b)
if(err != nil) {
log.Fatal(err)
return
} else {
fmt.Print("Wrote to destination socket: ",n, " bytes
")
}
time.Sleep(1000 * time.Millisecond)
}
}
When you use DialUDP
, you're creating a "connected" UDP socket, which only listens for datagrams from the given remote address. The underlying syscall is the same as connect
, which states in the man page:
If the socket sockfd is of type SOCK_DGRAM then addr is the address to which datagrams are sent by default, and the only address from which datagrams are received.
If you want to listen for any datagrams received on a particular UDP port, create the connection with ListenUDP
.
okey, i figured it out. first i have to apologize for not saying that i use windows(10)! This behaivor comes from the windows firewall. When it is turned off i can receive packets with different SOURCE ports in the reply.