nps/core/action/npc.go
2022-01-23 17:30:38 +08:00

85 lines
2.2 KiB
Go

package action
import (
"crypto/tls"
"ehang.io/nps/lib/cert"
"ehang.io/nps/lib/enet"
"ehang.io/nps/lib/pb"
"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
"net"
)
type NpcAction struct {
NpcId string `json:"npc_id" required:"true" placeholder:"npc id" zh_name:"客户端"`
BridgeAddr string `json:"bridge_addr" placeholder:"127.0.0.1:8080" zh_name:"网桥地址"`
UnixSocket bool `json:"unix_sock" placeholder:"" zh_name:"转发到unix socket"`
networkTcp pb.ConnType
tlsConfig *tls.Config
connRequest *pb.ConnRequest
DefaultAction
}
func (na *NpcAction) GetName() string {
return "npc"
}
func (na *NpcAction) GetZhName() string {
return "转发到客户端"
}
func (na *NpcAction) Init() error {
if na.tlsConfig == nil {
return errors.New("tls config is nil")
}
sn, err := cert.GetCertSnFromConfig(na.tlsConfig)
if err != nil {
return errors.Wrap(err, "get serial number")
}
na.connRequest = &pb.ConnRequest{Id: sn}
na.networkTcp = pb.ConnType_tcp
if na.UnixSocket {
// just support unix
na.networkTcp = pb.ConnType_unix
}
return nil
}
func (na *NpcAction) RunConnWithAddr(clientConn net.Conn, addr string) error {
serverConn, err := na.GetServeConnWithAddr(addr)
if err != nil {
return err
}
na.startCopy(clientConn, serverConn)
return nil
}
func (na *NpcAction) CanServe() bool {
return true
}
func (na *NpcAction) GetServeConnWithAddr(addr string) (net.Conn, error) {
return dialBridge(na, na.networkTcp, addr)
}
func (na *NpcAction) RunPacketConn(pc net.PacketConn) error {
serverPacketConn, err := dialBridge(na, pb.ConnType_udp, "")
if err != nil {
return err
}
return na.startCopyPacketConn(pc, enet.NewTcpPacketConn(serverPacketConn))
}
func dialBridge(npc *NpcAction, connType pb.ConnType, addr string) (net.Conn, error) {
tlsConn, err := tls.Dial("tcp", npc.BridgeAddr, npc.tlsConfig)
if err != nil {
return nil, errors.Wrap(err, "dial bridge tls")
}
cr := proto.Clone(npc.connRequest).(*pb.ConnRequest)
cr.ConnType = &pb.ConnRequest_AppInfo{AppInfo: &pb.AppInfo{ConnType: connType, AppAddr: addr, NpcId: npc.NpcId}}
if _, err = pb.WriteMessage(tlsConn, cr); err != nil {
return nil, errors.Wrap(err, "write enet request")
}
return tlsConn, err
}