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 }