/
main.go
94 lines (85 loc) · 2.14 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
"flag"
"fmt"
"log"
"net"
"sync"
"time"
)
type IpList struct {
sync.Mutex
Ips []string
}
var (
inport = flag.Int("inport", 2626, "the port for incoming registration packets")
bindaddr = flag.String("bindaddr", "0.0.0.0", "the address to listen on for incoming udp packets")
outport = flag.Int("outport", 2626, "the port on which to forward packets for all the hosts")
dnsname = flag.String("dnsname", "example.com", "the dns to resolve at each packet")
ttl = flag.Int("ttl", 60, "time in seconds to wait between each dns resolution")
ips = IpList{}
)
func gResolver(dns string, ttl int) {
log.Printf("starting resolution goroutine for %s with ttl %d", dns, ttl)
c := time.Tick(time.Duration(ttl) * time.Second)
for _ = range c {
ip, err := net.LookupHost(dns)
if err != nil {
log.Printf("Error resolving: %s: %s", dns, err)
} else {
log.Printf("Resolved %s as %s", dns, ip)
ips.Lock()
ips.Ips = ip
ips.Unlock()
}
}
}
func gSendToAddress(addr string, data []byte) {
udpaddr, err := net.ResolveUDPAddr("udp4", addr)
if err != nil {
log.Printf("cannot resolve %s: %s", addr, err)
return
}
conn, err := net.DialUDP("udp4", nil, udpaddr)
if err != nil {
log.Printf("cannot DialUDP to %s: %s", addr, err)
return
}
defer conn.Close()
_, err = conn.Write(data)
if err != nil {
log.Printf("cannot Write to %s: %s", addr, err)
return
}
}
func gHandleUdpPacket(data []byte) {
ips.Lock()
for _, ip := range ips.Ips {
go gSendToAddress(fmt.Sprintf("%s:%d", ip, *outport), data)
}
ips.Unlock()
}
func main() {
flag.Parse()
go gResolver(*dnsname, *ttl)
laddr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%d", *bindaddr, *inport))
if err != nil {
log.Printf("Cannot resolve %s:%d: %s", *bindaddr, *inport, err)
return
}
conn, err := net.ListenUDP("udp4", laddr)
if err != nil {
log.Printf("Cannot listen on %s: %s", laddr, err)
return
}
for {
b := make([]byte, 1500)
_, _, _, raddr, err := conn.ReadMsgUDP(b, nil)
if err != nil {
log.Printf("error reading udp message: %s", err)
return
}
log.Printf("got packet from: %s", raddr)
go gHandleUdpPacket(b)
}
}