mirror of
https://github.com/openp2p-cn/openp2p.git
synced 2025-12-24 12:57:52 +08:00
174 lines
5.5 KiB
Go
174 lines
5.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
func handlePush(pn *P2PNetwork, subType uint16, msg []byte) error {
|
|
pushHead := PushHeader{}
|
|
err := binary.Read(bytes.NewReader(msg[openP2PHeaderSize:openP2PHeaderSize+PushHeaderSize]), binary.LittleEndian, &pushHead)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
gLog.Printf(LevelDEBUG, "handle push msg type:%d, push header:%+v", subType, pushHead)
|
|
switch subType {
|
|
case MsgPushConnectReq:
|
|
req := PushConnectReq{}
|
|
err := json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req)
|
|
if err != nil {
|
|
gLog.Printf(LevelERROR, "wrong MsgPushConnectReq:%s", err)
|
|
return err
|
|
}
|
|
gLog.Printf(LevelINFO, "%s is connecting...", req.From)
|
|
gLog.Println(LevelDEBUG, "push connect response to ", req.From)
|
|
// verify token or name&password
|
|
if VerifyTOTP(req.Token, pn.config.User, pn.config.Password, time.Now().Unix()+(pn.serverTs-pn.localTs)) || // localTs may behind, auto adjust ts
|
|
VerifyTOTP(req.Token, pn.config.User, pn.config.Password, time.Now().Unix()) ||
|
|
(req.User == pn.config.User && req.Password == pn.config.Password) {
|
|
gLog.Printf(LevelINFO, "Access Granted\n")
|
|
config := AppConfig{}
|
|
config.peerNatType = req.NatType
|
|
config.peerConeNatPort = req.ConeNatPort
|
|
config.peerIP = req.FromIP
|
|
config.PeerNode = req.From
|
|
// share relay node will limit bandwidth
|
|
if req.User != pn.config.User || req.Password != pn.config.Password {
|
|
gLog.Printf(LevelINFO, "set share bandwidth %d mbps", pn.config.ShareBandwidth)
|
|
config.shareBandwidth = pn.config.ShareBandwidth
|
|
}
|
|
// go pn.AddTunnel(config, req.ID)
|
|
go pn.addDirectTunnel(config, req.ID)
|
|
break
|
|
}
|
|
gLog.Println(LevelERROR, "Access Denied:", req.From)
|
|
rsp := PushConnectRsp{
|
|
Error: 1,
|
|
Detail: fmt.Sprintf("connect to %s error: Access Denied", pn.config.Node),
|
|
To: req.From,
|
|
From: pn.config.Node,
|
|
}
|
|
pn.push(req.From, MsgPushConnectRsp, rsp)
|
|
case MsgPushRsp:
|
|
rsp := PushRsp{}
|
|
err := json.Unmarshal(msg[openP2PHeaderSize:], &rsp)
|
|
if err != nil {
|
|
gLog.Printf(LevelERROR, "wrong pushRsp:%s", err)
|
|
return err
|
|
}
|
|
if rsp.Error == 0 {
|
|
gLog.Printf(LevelDEBUG, "push ok, detail:%s", rsp.Detail)
|
|
} else {
|
|
gLog.Printf(LevelERROR, "push error:%d, detail:%s", rsp.Error, rsp.Detail)
|
|
}
|
|
case MsgPushAddRelayTunnelReq:
|
|
req := AddRelayTunnelReq{}
|
|
err := json.Unmarshal(msg[openP2PHeaderSize+PushHeaderSize:], &req)
|
|
if err != nil {
|
|
gLog.Printf(LevelERROR, "wrong RelayNodeRsp:%s", err)
|
|
return err
|
|
}
|
|
config := AppConfig{}
|
|
config.PeerNode = req.RelayName
|
|
config.peerToken = req.RelayToken
|
|
// set user password, maybe the relay node is your private node
|
|
config.PeerUser = pn.config.User
|
|
config.PeerPassword = pn.config.Password
|
|
go func(r AddRelayTunnelReq) {
|
|
t, errDt := pn.addDirectTunnel(config, 0)
|
|
if errDt == nil {
|
|
// notify peer relay ready
|
|
msg := TunnelMsg{ID: t.id}
|
|
pn.push(r.From, MsgPushAddRelayTunnelRsp, msg)
|
|
SaveKey(req.AppID, req.AppKey)
|
|
}
|
|
|
|
}(req)
|
|
case MsgPushUpdate:
|
|
update()
|
|
if gConf.daemonMode {
|
|
os.Exit(0)
|
|
}
|
|
case MsgPushReportApps:
|
|
gLog.Println(LevelINFO, "MsgPushReportApps")
|
|
req := ReportApps{}
|
|
// TODO: add the retrying apps
|
|
gConf.mtx.Lock()
|
|
defer gConf.mtx.Unlock()
|
|
for _, config := range gConf.Apps {
|
|
appInfo := AppInfo{
|
|
AppName: config.AppName,
|
|
Protocol: config.Protocol,
|
|
SrcPort: config.SrcPort,
|
|
// RelayNode: relayNode,
|
|
PeerNode: config.PeerNode,
|
|
DstHost: config.DstHost,
|
|
DstPort: config.DstPort,
|
|
PeerUser: config.PeerUser,
|
|
PeerIP: config.peerIP,
|
|
PeerNatType: config.peerNatType,
|
|
RetryTime: config.retryTime.String(),
|
|
IsActive: 1,
|
|
}
|
|
req.Apps = append(req.Apps, appInfo)
|
|
}
|
|
// pn.apps.Range(func(_, i interface{}) bool {
|
|
// app := i.(*p2pApp)
|
|
// appInfo := AppInfo{
|
|
// AppName: app.config.AppName,
|
|
// Protocol: app.config.Protocol,
|
|
// SrcPort: app.config.SrcPort,
|
|
// RelayNode: app.relayNode,
|
|
// PeerNode: app.config.PeerNode,
|
|
// DstHost: app.config.DstHost,
|
|
// DstPort: app.config.DstPort,
|
|
// PeerUser: app.config.PeerUser,
|
|
// PeerIP: app.config.peerIP,
|
|
// PeerNatType: app.config.peerNatType,
|
|
// RetryTime: app.config.retryTime.String(),
|
|
// IsActive: 1,
|
|
// }
|
|
// req.Apps = append(req.Apps, appInfo)
|
|
// return true
|
|
// })
|
|
pn.write(MsgReport, MsgReportApps, &req)
|
|
case MsgPushEditApp:
|
|
gLog.Println(LevelINFO, "MsgPushEditApp")
|
|
newApp := AppInfo{}
|
|
err := json.Unmarshal(msg[openP2PHeaderSize:], &newApp)
|
|
if err != nil {
|
|
gLog.Printf(LevelERROR, "wrong MsgPushEditApp:%s %s", err, string(msg[openP2PHeaderSize:]))
|
|
return err
|
|
}
|
|
var config AppConfig
|
|
// protocol0+srcPort0 exist, delApp
|
|
config.AppName = newApp.AppName
|
|
config.Protocol = newApp.Protocol0
|
|
config.SrcPort = newApp.SrcPort0
|
|
config.PeerNode = newApp.PeerNode
|
|
config.DstHost = newApp.DstHost
|
|
config.DstPort = newApp.DstPort
|
|
|
|
gConf.delete(config)
|
|
// AddApp
|
|
config.Protocol = newApp.Protocol
|
|
config.SrcPort = newApp.SrcPort
|
|
gConf.add(config)
|
|
gConf.save()
|
|
pn.DeleteApp(config) // save quickly for the next request reportApplist
|
|
// autoReconnect will auto AddApp
|
|
// pn.AddApp(config)
|
|
// TODO: report result
|
|
default:
|
|
pn.msgMapMtx.Lock()
|
|
ch := pn.msgMap[pushHead.From]
|
|
pn.msgMapMtx.Unlock()
|
|
ch <- msg
|
|
}
|
|
return nil
|
|
}
|