All checks were successful
Build Multi-Platform Binaries / build (push) Successful in 12m12s
66 lines
1.3 KiB
Go
66 lines
1.3 KiB
Go
package proxy
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
|
|
"github.com/gotunnel/pkg/protocol"
|
|
"github.com/hashicorp/yamux"
|
|
)
|
|
|
|
// TunnelDialer 通过隧道连接的拨号器
|
|
type TunnelDialer struct {
|
|
session *yamux.Session
|
|
}
|
|
|
|
// NewTunnelDialer 创建隧道拨号器
|
|
func NewTunnelDialer(session *yamux.Session) *TunnelDialer {
|
|
return &TunnelDialer{session: session}
|
|
}
|
|
|
|
// Dial 通过隧道建立连接
|
|
func (d *TunnelDialer) Dial(network, address string) (net.Conn, error) {
|
|
stream, err := d.session.Open()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 发送代理连接请求
|
|
req := protocol.ProxyConnectRequest{Target: address}
|
|
msg, err := protocol.NewMessage(protocol.MsgTypeProxyConnect, req)
|
|
if err != nil {
|
|
stream.Close()
|
|
return nil, err
|
|
}
|
|
|
|
if err := protocol.WriteMessage(stream, msg); err != nil {
|
|
stream.Close()
|
|
return nil, err
|
|
}
|
|
|
|
// 读取连接结果
|
|
respMsg, err := protocol.ReadMessage(stream)
|
|
if err != nil {
|
|
stream.Close()
|
|
return nil, err
|
|
}
|
|
|
|
if respMsg.Type != protocol.MsgTypeProxyResult {
|
|
stream.Close()
|
|
return nil, errors.New("unexpected response type")
|
|
}
|
|
|
|
var result protocol.ProxyConnectResult
|
|
if err := respMsg.ParsePayload(&result); err != nil {
|
|
stream.Close()
|
|
return nil, err
|
|
}
|
|
|
|
if !result.Success {
|
|
stream.Close()
|
|
return nil, errors.New(result.Message)
|
|
}
|
|
|
|
return stream, nil
|
|
}
|