mirror of
https://github.com/openp2p-cn/openp2p.git
synced 2025-09-26 20:51:15 +08:00
433 lines
12 KiB
Go
433 lines
12 KiB
Go
package openp2p
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"encoding/json"
|
|
"hash/crc64"
|
|
"math/big"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
const OpenP2PVersion = "3.5.0"
|
|
const ProducnName string = "openp2p"
|
|
const LeastSupportVersion = "3.0.0"
|
|
|
|
const (
|
|
IfconfigPort1 = 27180
|
|
IfconfigPort2 = 27181
|
|
WsPort = 27183
|
|
UDPPort1 = 27182
|
|
UDPPort2 = 27183
|
|
)
|
|
|
|
type openP2PHeader struct {
|
|
DataLen uint32
|
|
MainType uint16
|
|
SubType uint16
|
|
}
|
|
|
|
var openP2PHeaderSize = binary.Size(openP2PHeader{})
|
|
|
|
type PushHeader struct {
|
|
From uint64
|
|
To uint64
|
|
}
|
|
|
|
var PushHeaderSize = binary.Size(PushHeader{})
|
|
|
|
type overlayHeader struct {
|
|
id uint64
|
|
}
|
|
|
|
var overlayHeaderSize = binary.Size(overlayHeader{})
|
|
|
|
func decodeHeader(data []byte) (*openP2PHeader, error) {
|
|
head := openP2PHeader{}
|
|
rd := bytes.NewReader(data)
|
|
err := binary.Read(rd, binary.LittleEndian, &head)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &head, nil
|
|
}
|
|
|
|
func encodeHeader(mainType uint16, subType uint16, len uint32) []byte {
|
|
head := openP2PHeader{
|
|
len,
|
|
mainType,
|
|
subType,
|
|
}
|
|
headBuf := new(bytes.Buffer)
|
|
err := binary.Write(headBuf, binary.LittleEndian, head)
|
|
if err != nil {
|
|
return []byte("")
|
|
}
|
|
return headBuf.Bytes()
|
|
}
|
|
|
|
// Message type
|
|
const (
|
|
MsgLogin = 0
|
|
MsgHeartbeat = 1
|
|
MsgNATDetect = 2
|
|
MsgPush = 3
|
|
MsgP2P = 4
|
|
MsgRelay = 5
|
|
MsgReport = 6
|
|
MsgQuery = 7
|
|
)
|
|
|
|
// TODO: seperate node push and web push.
|
|
const (
|
|
MsgPushRsp = 0
|
|
MsgPushConnectReq = 1
|
|
MsgPushConnectRsp = 2
|
|
MsgPushHandshakeStart = 3
|
|
MsgPushAddRelayTunnelReq = 4
|
|
MsgPushAddRelayTunnelRsp = 5
|
|
MsgPushUpdate = 6
|
|
MsgPushReportApps = 7
|
|
MsgPushUnderlayConnect = 8
|
|
MsgPushEditApp = 9
|
|
MsgPushSwitchApp = 10
|
|
MsgPushRestart = 11
|
|
MsgPushEditNode = 12
|
|
MsgPushAPPKey = 13
|
|
MsgPushReportLog = 14
|
|
)
|
|
|
|
// MsgP2P sub type message
|
|
const (
|
|
MsgPunchHandshake = iota
|
|
MsgPunchHandshakeAck
|
|
MsgTunnelHandshake
|
|
MsgTunnelHandshakeAck
|
|
MsgTunnelHeartbeat
|
|
MsgTunnelHeartbeatAck
|
|
MsgOverlayConnectReq
|
|
MsgOverlayConnectRsp
|
|
MsgOverlayDisconnectReq
|
|
MsgOverlayData
|
|
MsgRelayData
|
|
MsgRelayHeartbeat
|
|
MsgRelayHeartbeatAck
|
|
)
|
|
|
|
// MsgRelay sub type message
|
|
const (
|
|
MsgRelayNodeReq = iota
|
|
MsgRelayNodeRsp
|
|
)
|
|
|
|
// MsgReport sub type message
|
|
const (
|
|
MsgReportBasic = iota
|
|
MsgReportQuery
|
|
MsgReportConnect
|
|
MsgReportApps
|
|
MsgReportLog
|
|
)
|
|
|
|
const (
|
|
ReadBuffLen = 4096 // for UDP maybe not enough
|
|
NetworkHeartbeatTime = time.Second * 30 // TODO: server no response hb, save flow
|
|
TunnelHeartbeatTime = time.Second * 15
|
|
TunnelIdleTimeout = time.Minute
|
|
SymmetricHandshakeNum = 800 // 0.992379
|
|
// SymmetricHandshakeNum = 1000 // 0.999510
|
|
SymmetricHandshakeInterval = time.Millisecond
|
|
SymmetricHandshakeAckTimeout = time.Second * 11
|
|
PeerAddRelayTimeount = time.Second * 20
|
|
CheckActiveTimeout = time.Second * 5
|
|
PaddingSize = 16
|
|
AESKeySize = 16
|
|
MaxRetry = 10
|
|
RetryInterval = time.Second * 30
|
|
PublicIPEchoTimeout = time.Second * 1
|
|
NatTestTimeout = time.Second * 10
|
|
ClientAPITimeout = time.Second * 10
|
|
MaxDirectTry = 3
|
|
)
|
|
|
|
// NATNone has public ip
|
|
const (
|
|
NATNone = 0
|
|
NATCone = 1
|
|
NATSymmetric = 2
|
|
NATUnknown = 314
|
|
)
|
|
|
|
// underlay protocol
|
|
const (
|
|
UderlayAuto = "auto"
|
|
UderlayQUIC = "quic"
|
|
UderlayTCP = "tcp"
|
|
)
|
|
|
|
// linkmode
|
|
const (
|
|
LinkModeUDPPunch = "udppunch"
|
|
LinkModeTCPPunch = "tcppunch"
|
|
LinkModeIPv4 = "ipv4" // for web
|
|
LinkModeIPv6 = "ipv6" // for web
|
|
LinkModeTCP6 = "tcp6"
|
|
LinkModeTCP4 = "tcp4"
|
|
LinkModeUDP6 = "udp6"
|
|
LinkModeUDP4 = "udp4"
|
|
)
|
|
|
|
const (
|
|
MsgQueryPeerInfoReq = iota
|
|
MsgQueryPeerInfoRsp
|
|
)
|
|
|
|
func newMessage(mainType uint16, subType uint16, packet interface{}) ([]byte, error) {
|
|
data, err := json.Marshal(packet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// gLog.Println(LevelINFO,"write packet:", string(data))
|
|
head := openP2PHeader{
|
|
uint32(len(data)),
|
|
mainType,
|
|
subType,
|
|
}
|
|
headBuf := new(bytes.Buffer)
|
|
err = binary.Write(headBuf, binary.LittleEndian, head)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
writeBytes := append(headBuf.Bytes(), data...)
|
|
return writeBytes, nil
|
|
}
|
|
|
|
func nodeNameToID(name string) uint64 {
|
|
return crc64.Checksum([]byte(name), crc64.MakeTable(crc64.ISO))
|
|
}
|
|
|
|
type PushConnectReq struct {
|
|
From string `json:"from,omitempty"`
|
|
FromToken uint64 `json:"fromToken,omitempty"` // deprecated
|
|
Version string `json:"version,omitempty"`
|
|
Token uint64 `json:"token,omitempty"` // if public totp token
|
|
ConeNatPort int `json:"coneNatPort,omitempty"` // if isPublic, is public port
|
|
NatType int `json:"natType,omitempty"`
|
|
HasIPv4 int `json:"hasIPv4,omitempty"`
|
|
IPv6 string `json:"IPv6,omitempty"`
|
|
HasUPNPorNATPMP int `json:"hasUPNPorNATPMP,omitempty"`
|
|
FromIP string `json:"fromIP,omitempty"`
|
|
ID uint64 `json:"id,omitempty"`
|
|
AppKey uint64 `json:"appKey,omitempty"` // for underlay tcp
|
|
LinkMode string `json:"linkMode,omitempty"`
|
|
IsUnderlayServer int `json:"isServer,omitempty"` // Requset spec peer is server
|
|
}
|
|
type PushConnectRsp struct {
|
|
Error int `json:"error,omitempty"`
|
|
From string `json:"from,omitempty"`
|
|
To string `json:"to,omitempty"`
|
|
Detail string `json:"detail,omitempty"`
|
|
NatType int `json:"natType,omitempty"`
|
|
HasIPv4 int `json:"hasIPv4,omitempty"`
|
|
IPv6 string `json:"IPv6,omitempty"` // if public relay node, ipv6 not set
|
|
HasUPNPorNATPMP int `json:"hasUPNPorNATPMP,omitempty"`
|
|
ConeNatPort int `json:"coneNatPort,omitempty"` //it's not only cone, but also upnp or nat-pmp hole
|
|
FromIP string `json:"fromIP,omitempty"`
|
|
ID uint64 `json:"id,omitempty"`
|
|
Version string `json:"version,omitempty"`
|
|
}
|
|
type PushRsp struct {
|
|
Error int `json:"error,omitempty"`
|
|
Detail string `json:"detail,omitempty"`
|
|
}
|
|
|
|
type LoginRsp struct {
|
|
Error int `json:"error,omitempty"`
|
|
Detail string `json:"detail,omitempty"`
|
|
User string `json:"user,omitempty"`
|
|
Node string `json:"node,omitempty"`
|
|
Token uint64 `json:"token,omitempty"`
|
|
Ts int64 `json:"ts,omitempty"`
|
|
}
|
|
|
|
type NatDetectReq struct {
|
|
SrcPort int `json:"srcPort,omitempty"`
|
|
EchoPort int `json:"echoPort,omitempty"`
|
|
}
|
|
|
|
type NatDetectRsp struct {
|
|
IP string `json:"IP,omitempty"`
|
|
Port int `json:"port,omitempty"`
|
|
IsPublicIP int `json:"isPublicIP,omitempty"`
|
|
}
|
|
|
|
type P2PHandshakeReq struct {
|
|
ID uint64 `json:"id,omitempty"`
|
|
}
|
|
|
|
type OverlayConnectReq struct {
|
|
ID uint64 `json:"id,omitempty"`
|
|
Token uint64 `json:"token,omitempty"` // not totp token
|
|
DstIP string `json:"dstIP,omitempty"`
|
|
DstPort int `json:"dstPort,omitempty"`
|
|
Protocol string `json:"protocol,omitempty"`
|
|
RelayTunnelID uint64 `json:"relayTunnelID,omitempty"` // if not 0 relay
|
|
AppID uint64 `json:"appID,omitempty"`
|
|
}
|
|
type OverlayDisconnectReq struct {
|
|
ID uint64 `json:"id,omitempty"`
|
|
}
|
|
type TunnelMsg struct {
|
|
ID uint64 `json:"id,omitempty"`
|
|
}
|
|
|
|
type RelayNodeReq struct {
|
|
PeerNode string `json:"peerNode,omitempty"`
|
|
}
|
|
|
|
type RelayNodeRsp struct {
|
|
Mode string `json:"mode,omitempty"` // private,public
|
|
RelayName string `json:"relayName,omitempty"`
|
|
RelayToken uint64 `json:"relayToken,omitempty"`
|
|
}
|
|
|
|
type AddRelayTunnelReq struct {
|
|
From string `json:"from,omitempty"`
|
|
RelayName string `json:"relayName,omitempty"`
|
|
RelayToken uint64 `json:"relayToken,omitempty"`
|
|
AppID uint64 `json:"appID,omitempty"` // deprecated
|
|
AppKey uint64 `json:"appKey,omitempty"` // deprecated
|
|
}
|
|
|
|
type APPKeySync struct {
|
|
AppID uint64 `json:"appID,omitempty"`
|
|
AppKey uint64 `json:"appKey,omitempty"`
|
|
}
|
|
|
|
type RelayHeartbeat struct {
|
|
RelayTunnelID uint64 `json:"relayTunnelID,omitempty"`
|
|
AppID uint64 `json:"appID,omitempty"`
|
|
}
|
|
|
|
type ReportBasic struct {
|
|
OS string `json:"os,omitempty"`
|
|
Mac string `json:"mac,omitempty"`
|
|
LanIP string `json:"lanIP,omitempty"`
|
|
HasIPv4 int `json:"hasIPv4,omitempty"`
|
|
IPv6 string `json:"IPv6,omitempty"`
|
|
HasUPNPorNATPMP int `json:"hasUPNPorNATPMP,omitempty"`
|
|
Version string `json:"version,omitempty"`
|
|
NetInfo NetInfo `json:"netInfo,omitempty"`
|
|
}
|
|
|
|
type ReportConnect struct {
|
|
Error string `json:"error,omitempty"`
|
|
Protocol string `json:"protocol,omitempty"`
|
|
SrcPort int `json:"srcPort,omitempty"`
|
|
NatType int `json:"natType,omitempty"`
|
|
PeerNode string `json:"peerNode,omitempty"`
|
|
DstPort int `json:"dstPort,omitempty"`
|
|
DstHost string `json:"dstHost,omitempty"`
|
|
PeerUser string `json:"peerUser,omitempty"`
|
|
PeerNatType int `json:"peerNatType,omitempty"`
|
|
PeerIP string `json:"peerIP,omitempty"`
|
|
ShareBandwidth int `json:"shareBandWidth,omitempty"`
|
|
RelayNode string `json:"relayNode,omitempty"`
|
|
Version string `json:"version,omitempty"`
|
|
}
|
|
|
|
type AppInfo struct {
|
|
AppName string `json:"appName,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
Protocol string `json:"protocol,omitempty"`
|
|
SrcPort int `json:"srcPort,omitempty"`
|
|
Protocol0 string `json:"protocol0,omitempty"`
|
|
SrcPort0 int `json:"srcPort0,omitempty"`
|
|
NatType int `json:"natType,omitempty"`
|
|
PeerNode string `json:"peerNode,omitempty"`
|
|
DstPort int `json:"dstPort,omitempty"`
|
|
DstHost string `json:"dstHost,omitempty"`
|
|
PeerUser string `json:"peerUser,omitempty"`
|
|
PeerNatType int `json:"peerNatType,omitempty"`
|
|
PeerIP string `json:"peerIP,omitempty"`
|
|
ShareBandwidth int `json:"shareBandWidth,omitempty"`
|
|
RelayNode string `json:"relayNode,omitempty"`
|
|
RelayMode string `json:"relayMode,omitempty"`
|
|
LinkMode string `json:"linkMode,omitempty"`
|
|
Version string `json:"version,omitempty"`
|
|
RetryTime string `json:"retryTime,omitempty"`
|
|
ConnectTime string `json:"connectTime,omitempty"`
|
|
IsActive int `json:"isActive,omitempty"`
|
|
Enabled int `json:"enabled,omitempty"`
|
|
}
|
|
|
|
type ReportApps struct {
|
|
Apps []AppInfo
|
|
}
|
|
|
|
type ReportLogReq struct {
|
|
FileName string `json:"fileName,omitempty"`
|
|
Offset int64 `json:"offset,omitempty"`
|
|
Len int64 `json:"len,omitempty"`
|
|
}
|
|
type ReportLogRsp struct {
|
|
FileName string `json:"fileName,omitempty"`
|
|
Content string `json:"content,omitempty"`
|
|
Len int64 `json:"len,omitempty"`
|
|
Total int64 `json:"total,omitempty"`
|
|
}
|
|
|
|
type UpdateInfo struct {
|
|
Error int `json:"error,omitempty"`
|
|
ErrorDetail string `json:"errorDetail,omitempty"`
|
|
Url string `json:"url,omitempty"`
|
|
}
|
|
|
|
type NetInfo struct {
|
|
IP net.IP `json:"ip"`
|
|
IPDecimal *big.Int `json:"ip_decimal"`
|
|
Country string `json:"country,omitempty"`
|
|
CountryISO string `json:"country_iso,omitempty"`
|
|
CountryEU *bool `json:"country_eu,omitempty"`
|
|
RegionName string `json:"region_name,omitempty"`
|
|
RegionCode string `json:"region_code,omitempty"`
|
|
MetroCode uint `json:"metro_code,omitempty"`
|
|
PostalCode string `json:"zip_code,omitempty"`
|
|
City string `json:"city,omitempty"`
|
|
Latitude float64 `json:"latitude,omitempty"`
|
|
Longitude float64 `json:"longitude,omitempty"`
|
|
Timezone string `json:"time_zone,omitempty"`
|
|
ASN string `json:"asn,omitempty"`
|
|
ASNOrg string `json:"asn_org,omitempty"`
|
|
Hostname string `json:"hostname,omitempty"`
|
|
}
|
|
|
|
type ProfileInfo struct {
|
|
User string `json:"user,omitempty"`
|
|
Password string `json:"password,omitempty"`
|
|
Email string `json:"email,omitempty"`
|
|
Phone string `json:"phone,omitempty"`
|
|
Token string `json:"token,omitempty"`
|
|
Addtime string `json:"addtime,omitempty"`
|
|
}
|
|
|
|
type EditNode struct {
|
|
NewName string `json:"newName,omitempty"`
|
|
Bandwidth int `json:"bandwidth,omitempty"`
|
|
}
|
|
|
|
type QueryPeerInfoReq struct {
|
|
Token uint64 `json:"token,omitempty"` // if public totp token
|
|
PeerNode string `json:"peerNode,omitempty"`
|
|
}
|
|
type QueryPeerInfoRsp struct {
|
|
Online int `json:"online,omitempty"`
|
|
Version string `json:"version,omitempty"`
|
|
NatType int `json:"natType,omitempty"`
|
|
IPv4 string `json:"IPv4,omitempty"`
|
|
HasIPv4 int `json:"hasIPv4,omitempty"` // has public ipv4
|
|
IPv6 string `json:"IPv6,omitempty"` // if public relay node, ipv6 not set
|
|
HasUPNPorNATPMP int `json:"hasUPNPorNATPMP,omitempty"`
|
|
}
|