BuckarooBanzay 54a5dbd193 ping command
2022-04-02 20:22:33 +02:00

62 lines
1.1 KiB
Go

package main
import (
"encoding/binary"
"errors"
"fmt"
"net"
"time"
)
var INIT_PKG = []byte{0x4f, 0x45, 0x74, 0x03, 0x00, 0x00, 0x00, 0x01}
func createDiscoPkg(peer_id uint16) []byte {
pkg := []byte{0x4f, 0x45, 0x74, 0x03, 0xff, 0xff, 0x00, 0x00, 0x03}
binary.BigEndian.PutUint16(pkg[4:], peer_id)
return pkg
}
type PingResult struct {
Delay time.Duration
PeerID uint16
}
func Ping(host string, port int) (*PingResult, error) {
conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port))
if err != nil {
return nil, err
}
defer conn.Close()
start := time.Now()
conn.Write(INIT_PKG)
buf := make([]byte, 128)
count, err := conn.Read(buf)
if err != nil {
return nil, err
} else if count == 0 {
return nil, errors.New("no data received")
} else if count != 14 {
return nil, fmt.Errorf("invalid packet received: len=%d", count)
}
res := &PingResult{
Delay: time.Now().Sub(start),
PeerID: binary.BigEndian.Uint16(buf[12:]),
}
disco := createDiscoPkg(res.PeerID)
_, err = conn.Write(disco)
if err != nil {
return nil, err
}
return res, nil
}