WIP
This commit is contained in:
parent
485003204f
commit
b4a6149cee
32
peer/packets-helpers.go
Normal file
32
peer/packets-helpers.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package peer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func unmarshalPacket(nonce Nonce, data []byte) Packet {
|
||||||
|
var packet Packet
|
||||||
|
|
||||||
|
switch nonce.PacketType {
|
||||||
|
case PACKET_TYPE_PING:
|
||||||
|
packet = &Ping{}
|
||||||
|
case PACKET_TYPE_PONG:
|
||||||
|
packet = &Pong{}
|
||||||
|
case PACKET_TYPE_LIST_ADDR_REQ:
|
||||||
|
packet = &AddrListReq{}
|
||||||
|
case PACKET_TYPE_LIST_ADDR_RESP:
|
||||||
|
packet = &AddrListResp{}
|
||||||
|
default:
|
||||||
|
// TODO: Log.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) < packet.Size() {
|
||||||
|
log.Printf("Short packet[%d]: %d", nonce.PacketType, len(data))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
packet.Parse(data[:packet.Size()])
|
||||||
|
|
||||||
|
return packet
|
||||||
|
}
|
138
peer/packets.go
Normal file
138
peer/packets.go
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
package peer
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
const (
|
||||||
|
PACKET_TYPE_DATA = 0
|
||||||
|
PACKET_TYPE_PING = 1
|
||||||
|
PACKET_TYPE_PONG = 2
|
||||||
|
PACKET_TYPE_CONN_REQ = 3
|
||||||
|
PACKET_TYPE_CONN_RESP = 4
|
||||||
|
PACKET_TYPE_CONN_RESP_ACK = 5
|
||||||
|
PACKET_TYPE_LIST_ADDR_REQ = 6
|
||||||
|
PACKET_TYPE_LIST_ADDR_RESP = 7
|
||||||
|
|
||||||
|
CONN_REQ_SIZE = 24
|
||||||
|
CONN_RESP_SIZE = 8
|
||||||
|
CONN_RESP_ACK_SIZE = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
type Packet interface {
|
||||||
|
Size() int
|
||||||
|
Parse(buf []byte)
|
||||||
|
Marshal(buf []byte) []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type AddrListReq struct{} // Nothing.
|
||||||
|
|
||||||
|
func (r *AddrListReq) Size() int { return 0 }
|
||||||
|
|
||||||
|
func (r *AddrListReq) Parse(buf []byte) {}
|
||||||
|
|
||||||
|
func (r *AddrListReq) Marshal(buf []byte) []byte { return buf[:0] }
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type AddrListResp struct {
|
||||||
|
Addrs [][16]byte // All addresses are IPv6 or mapped IPv6.
|
||||||
|
Ports []uint16 // Ports.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *AddrListResp) Size() int {
|
||||||
|
return 18 * MAX_IP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *AddrListResp) Parse(buf []byte) {
|
||||||
|
r.Addrs = unsafe.Slice((*[16]byte)(unsafe.Pointer(&buf[0])), MAX_IP)
|
||||||
|
r.Ports = unsafe.Slice((*uint16)(unsafe.Pointer(&buf[16*MAX_IP])), MAX_IP)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *AddrListResp) Marshal(buf []byte) []byte {
|
||||||
|
buf = buf[:18:MAX_IP]
|
||||||
|
addrs := unsafe.Slice((*[16]byte)(unsafe.Pointer(&buf[0])), MAX_IP)
|
||||||
|
copy(addrs, r.Addrs)
|
||||||
|
ports := unsafe.Slice((*uint16)(unsafe.Pointer(&buf[16*MAX_IP])), MAX_IP)
|
||||||
|
copy(ports, r.Ports)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type ConnReq struct {
|
||||||
|
ReqID uint64
|
||||||
|
SentAt int64
|
||||||
|
Tiebreaker int64 // To determine which side is client or server.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ConnReq) Parse(buf []byte) {
|
||||||
|
r.ReqID = *(*uint64)(unsafe.Pointer(&buf[0]))
|
||||||
|
r.SentAt = *(*int64)(unsafe.Pointer(&buf[8]))
|
||||||
|
r.Tiebreaker = *(*int64)(unsafe.Pointer(&buf[16]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ConnReq) Marshal(buf []byte) []byte {
|
||||||
|
buf = buf[:24]
|
||||||
|
*(*uint64)(unsafe.Pointer(&buf[0])) = r.ReqID
|
||||||
|
*(*int64)(unsafe.Pointer(&buf[8])) = r.SentAt
|
||||||
|
*(*int64)(unsafe.Pointer(&buf[16])) = r.Tiebreaker
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type ConnResp struct {
|
||||||
|
ReqID uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ConnResp) Parse(buf []byte) {
|
||||||
|
r.ReqID = *(*uint64)(unsafe.Pointer(&buf[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ConnResp) Marshal(buf []byte) {
|
||||||
|
*(*uint64)(unsafe.Pointer(&buf[0])) = r.ReqID
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type ConnRespAck = ConnResp
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type Ping struct {
|
||||||
|
SentAt int64 // unix milli
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Ping) Size() int { return 8 }
|
||||||
|
|
||||||
|
func (p *Ping) Parse(buf []byte) {
|
||||||
|
p.SentAt = *(*int64)(unsafe.Pointer(&buf[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Ping) Marshal(buf []byte) []byte {
|
||||||
|
buf = buf[:8]
|
||||||
|
*(*int64)(unsafe.Pointer(&buf[0])) = p.SentAt
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type Pong struct {
|
||||||
|
SentAt int64 // unix mili
|
||||||
|
RecvdAt int64 // unix mili
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pong) Size() int { return 16 }
|
||||||
|
|
||||||
|
func (p *Pong) Parse(buf []byte) {
|
||||||
|
p.SentAt = *(*int64)(unsafe.Pointer(&buf[0]))
|
||||||
|
p.RecvdAt = *(*int64)(unsafe.Pointer(&buf[8]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pong) Marshal(buf []byte) []byte {
|
||||||
|
buf = buf[:16]
|
||||||
|
*(*int64)(unsafe.Pointer(&buf[0])) = p.SentAt
|
||||||
|
*(*int64)(unsafe.Pointer(&buf[8])) = p.RecvdAt
|
||||||
|
return buf
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user