79 Star 452 Fork 170

王敏/golang内网穿透

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
inner_connection.go 3.16 KB
一键复制 编辑 原始数据 按行查看 历史
王敏 提交于 5年前 . 关闭io.copy提示
/**
* @Time: 2019/1/15 14:50
* @Author: wangmin
* @File: inner_connection.go
* @Software: GoLand
*/
package connection
import (
"encoding/json"
"io"
"log"
"net"
"strconv"
"strings"
"time"
"transponder/event"
)
const StatusInit = 0
const StatusOk = 2
const StatusProxy = 3
const StatusClose = 4
// 内部连接对象
type InnerConnection struct {
Id uint64 // 连接id
Status int // 连接状态
AuthKey string // 授权码
Created int64 // 创建时间
Conn net.Conn // 内网服务连接对象
proxyConn net.Conn // 外网连接
StatusMonitor func(id uint64, status int)
}
// 读取内网服务器上行数据
func (ic *InnerConnection) Read() {
for {
if ic.Status == StatusProxy || ic.Status == StatusClose {
return
}
buf := make([]byte, event.PackageLength)
n, err := ic.Conn.Read(buf)
if err != nil {
log.Println("read from inner server connection error:" + err.Error())
ic.Close()
return
}
if n != event.PackageLength {
log.Println("read from inner server connection error data length error")
ic.Close()
return
}
signal := &event.Signal{}
err = json.Unmarshal(buf, signal)
if err != nil {
log.Println("cant not parse inner server signal data:" + string(buf) + " error:" + err.Error())
ic.Close()
return
}
switch signal.T {
case event.Ping:
// do nothing
case event.Auth:
if strings.TrimRight(signal.Ext, " ") != ic.AuthKey {
log.Println("auth key " + ic.AuthKey + " != " + signal.Ext)
ic.Close()
return
}
ic.Status = StatusOk
ic.StatusMonitor(ic.Id, StatusOk)
case event.StartProxy:
ic.Status = StatusProxy
ic.StatusMonitor(ic.Id, StatusProxy)
ic.startProxy()
return
default:
log.Println("unknown inner server event:" + strconv.Itoa(signal.T))
ic.Close()
return
}
}
}
// 开始转发
func (ic *InnerConnection) ProxyRequest(conn net.Conn) {
ic.proxyConn = conn
_, err := ic.Conn.Write(event.GenerateSignal(event.StartProxy, ""))
if err != nil {
log.Println("send request fail:" + err.Error())
ic.Close()
return
}
time.AfterFunc(time.Second*5, func() {
if ic.Status != StatusProxy && ic.Status != StatusClose {
log.Println("wait for inner service timeout")
ic.Close()
}
})
}
// 开始转发
func (ic *InnerConnection) startProxy() {
// log.Println("外部服务开始转发")
_ = ic.Conn.SetReadDeadline(time.Now().Add(time.Second * 30))
_ = ic.Conn.SetWriteDeadline(time.Now().Add(time.Second * 30))
_ = ic.proxyConn.SetReadDeadline(time.Now().Add(time.Second * 30))
_ = ic.proxyConn.SetWriteDeadline(time.Now().Add(time.Second * 30))
go func() {
if ic.proxyConn != nil && ic.Conn != nil {
_, _ = io.Copy(ic.proxyConn, ic.Conn)
}
if ic.proxyConn != nil {
_ = ic.proxyConn.Close()
}
}()
go func() {
if ic.Conn != nil && ic.proxyConn != nil {
_, _ = io.Copy(ic.Conn, ic.proxyConn)
}
if ic != nil {
ic.Close()
}
}()
}
// 关闭连接
func (ic *InnerConnection) Close() {
ic.Status = StatusClose
ic.StatusMonitor(ic.Id, StatusClose)
if ic.Conn != nil {
_ = ic.Conn.Close()
ic.Conn = nil
}
if ic.proxyConn != nil {
_ = ic.proxyConn.Close()
ic.proxyConn = nil
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/stlswm/transponder.git
git@gitee.com:stlswm/transponder.git
stlswm
transponder
golang内网穿透
master

搜索帮助