mirror of
https://github.com/sigcn/pg.git
synced 2025-10-06 07:06:52 +08:00
64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package udp
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
|
|
"github.com/sigcn/pg/disco"
|
|
)
|
|
|
|
var (
|
|
MAGIC_TO_RELAY = []byte{'_', 'p', 'g', 1}
|
|
MAGIC_FROM_RELAY = []byte{'_', 'p', 'g', 3}
|
|
)
|
|
|
|
type RelayToPeerError struct {
|
|
PeerID disco.PeerID
|
|
err error
|
|
}
|
|
|
|
func (e RelayToPeerError) Error() string {
|
|
return fmt.Errorf("relay to %s : %w", e.PeerID, e.err).Error()
|
|
}
|
|
|
|
func (e RelayToPeerError) Unwrap() error {
|
|
return e.err
|
|
}
|
|
|
|
type relayProtocol struct {
|
|
}
|
|
|
|
// toRelay make a udp packet later send to relay
|
|
func (proto *relayProtocol) toRelay(p []byte, dst disco.PeerID) []byte {
|
|
pkt := append([]byte(nil), MAGIC_TO_RELAY...)
|
|
pkt = append(pkt, dst.Len())
|
|
pkt = append(pkt, dst.Bytes()...)
|
|
pkt = append(pkt, p...)
|
|
return pkt
|
|
}
|
|
|
|
// tryToDst decode udp packet and make a udp packet later send to dest if it is a relay_to packet
|
|
func (proto *relayProtocol) tryToDst(p []byte, src disco.PeerID) ([]byte, disco.PeerID) {
|
|
if !bytes.Equal(MAGIC_TO_RELAY, p[:4]) {
|
|
return nil, ""
|
|
}
|
|
return proto.toDst(p[5+p[4]:], src), disco.PeerID(p[5 : 5+p[4]])
|
|
}
|
|
|
|
// tryRecv decode udp packet and return datagram if it is a relay_from packet
|
|
func (proto *relayProtocol) tryRecv(p []byte) ([]byte, disco.PeerID) {
|
|
if !bytes.Equal(MAGIC_FROM_RELAY, p[:4]) {
|
|
return nil, ""
|
|
}
|
|
return append([]byte(nil), p[5+p[4]:]...), disco.PeerID(p[5 : 5+p[4]])
|
|
}
|
|
|
|
// toDst make a udp packet later send to dest
|
|
func (proto *relayProtocol) toDst(p []byte, src disco.PeerID) []byte {
|
|
pkt := append([]byte(nil), MAGIC_FROM_RELAY...)
|
|
pkt = append(pkt, src.Len())
|
|
pkt = append(pkt, src.Bytes()...)
|
|
pkt = append(pkt, p...)
|
|
return pkt
|
|
}
|