syncthing/cmd/discosrv/main.go

100 lines
1.6 KiB
Go

package main
import (
"log"
"net"
"sync"
"time"
"github.com/calmh/syncthing/discover"
)
type Node struct {
IP []byte
Port uint16
Updated time.Time
}
var (
nodes = make(map[string]Node)
lock sync.Mutex
queries = 0
)
func main() {
addr, _ := net.ResolveUDPAddr("udp", ":22025")
conn, err := net.ListenUDP("udp", addr)
if err != nil {
panic(err)
}
go func() {
for {
time.Sleep(600 * time.Second)
lock.Lock()
var deleted = 0
for id, node := range nodes {
if time.Since(node.Updated) > 60*time.Minute {
delete(nodes, id)
deleted++
}
}
log.Printf("Expired %d nodes; %d nodes in registry; %d queries", deleted, len(nodes), queries)
queries = 0
lock.Unlock()
}
}()
var buf = make([]byte, 1024)
for {
n, addr, err := conn.ReadFromUDP(buf)
if err != nil {
panic(err)
}
pkt, err := discover.DecodePacket(buf[:n])
if err != nil {
log.Println("Warning:", err)
continue
}
switch pkt.Magic {
case 0x20121025:
// Announcement
lock.Lock()
ip := addr.IP.To4()
if ip == nil {
ip = addr.IP.To16()
}
node := Node{
IP: ip,
Port: uint16(pkt.Port),
Updated: time.Now(),
}
//log.Println("<-", pkt.ID, node)
nodes[pkt.ID] = node
lock.Unlock()
case 0x19760309:
// Query
lock.Lock()
node, ok := nodes[pkt.ID]
queries++
lock.Unlock()
if ok {
pkt := discover.Packet{
Magic: 0x20121025,
ID: pkt.ID,
Port: node.Port,
IP: node.IP,
}
_, _, err = conn.WriteMsgUDP(discover.EncodePacket(pkt), nil, addr)
if err != nil {
log.Println("Warning:", err)
}
}
}
}
}