Files
sing-box-extended/transport/trusttunnel/icmp.go

63 lines
1.6 KiB
Go

package trusttunnel
import (
"encoding/binary"
"net/netip"
"github.com/sagernet/sing/common/buf"
)
type IcmpConn struct {
httpConn
}
func (i *IcmpConn) WritePing(id uint16, destination netip.Addr, sequenceNumber uint16, ttl uint8, size uint16) error {
request := buf.NewSize(2 + 16 + 2 + 1 + 2)
defer request.Release()
must(binary.Write(request, binary.BigEndian, id))
destinationAddress := buildPaddingIP(destination)
must1(request.Write(destinationAddress[:]))
must(binary.Write(request, binary.BigEndian, sequenceNumber))
must(binary.Write(request, binary.BigEndian, ttl))
must(binary.Write(request, binary.BigEndian, size))
_, err := i.writeFlush(request.Bytes())
return err
}
func (i *IcmpConn) ReadPing() (id uint16, sourceAddress netip.Addr, icmpType uint8, code uint8, sequenceNumber uint16, err error) {
err = i.waitCreated()
if err != nil {
return
}
response := buf.NewSize(2 + 16 + 1 + 1 + 2)
defer response.Release()
_, err = response.ReadFullFrom(i.body, response.FreeLen())
if err != nil {
return
}
must(binary.Read(response, binary.BigEndian, &id))
var sourceAddressBuffer [16]byte
must1(response.Read(sourceAddressBuffer[:]))
sourceAddress = parse16BytesIP(sourceAddressBuffer)
must(binary.Read(response, binary.BigEndian, &icmpType))
must(binary.Read(response, binary.BigEndian, &code))
must(binary.Read(response, binary.BigEndian, &sequenceNumber))
return
}
func (i *IcmpConn) Close() error {
return i.httpConn.Close()
}
func must(err error) {
if err != nil {
panic(err)
}
}
func must1[T any](_ T, err error) {
if err != nil {
panic(err)
}
}