Files
Meshray-Manager/core/connect/real_tcp.go
T
2026-06-30 15:14:37 +08:00

182 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package connect
import (
"context"
"fmt"
"net"
"sync"
"time"
"go.uber.org/zap"
)
// RealTCPConn 真正的 TCP 连接(用于传输 WireGuard 密文)
// 与 FakeTCP 不同,RealTCP 不封装 UDP 包,直接传输原始数据
type RealTCPConn struct {
conn net.Conn
closed bool
mu sync.Mutex
}
// NewRealTCPConn 创建 RealTCP 连接
func NewRealTCPConn(conn net.Conn) *RealTCPConn {
return &RealTCPConn{
conn: conn,
}
}
// Read 读取数据
func (c *RealTCPConn) Read(b []byte) (int, error) {
c.mu.Lock()
defer c.mu.Unlock()
if c.closed {
return 0, fmt.Errorf("connection closed")
}
return c.conn.Read(b)
}
// Write 写入数据
func (c *RealTCPConn) Write(b []byte) (int, error) {
c.mu.Lock()
defer c.mu.Unlock()
if c.closed {
return 0, fmt.Errorf("connection closed")
}
return c.conn.Write(b)
}
// Close 关闭连接
func (c *RealTCPConn) Close() error {
c.mu.Lock()
defer c.mu.Unlock()
c.closed = true
return c.conn.Close()
}
// RealTCPFactory RealTCP 传输工厂
type RealTCPFactory struct {
logger *zap.Logger
}
// NewRealTCPFactory 创建 RealTCP 工厂
func NewRealTCPFactory(logger *zap.Logger) *RealTCPFactory {
return &RealTCPFactory{
logger: logger,
}
}
// Layer 返回传输层类型
func (f *RealTCPFactory) Layer() Layer {
return LayerRealTCP
}
// Name 返回名称
func (f *RealTCPFactory) Name() string {
return "RealTCP"
}
// Dial 建立 RealTCP 连接
func (f *RealTCPFactory) Dial(ctx context.Context, config *DialConfig) (net.Conn, error) {
f.logger.Info("开始建立 RealTCP 连接",
zap.String("peer_id", config.PeerID))
// 1. 解析对端地址(PeerID 格式应为 "ip:port"
if config.PeerID == "" {
return nil, fmt.Errorf("PeerID 为空")
}
// 2. 建立 TCP 连接
dialer := &net.Dialer{Timeout: config.Timeout}
conn, err := dialer.DialContext(ctx, "tcp", config.PeerID)
if err != nil {
return nil, fmt.Errorf("TCP 连接失败:%w", err)
}
// 3. 包装为 RealTCP 连接(直接传输原始数据)
realConn := NewRealTCPConn(conn)
f.logger.Info("RealTCP 连接建立成功",
zap.String("peer_id", config.PeerID),
zap.String("local_addr", conn.LocalAddr().String()),
zap.String("remote_addr", conn.RemoteAddr().String()))
return realConn, nil
}
// LocalAddr 本地地址
func (c *RealTCPConn) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}
// RemoteAddr 远程地址
func (c *RealTCPConn) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
}
// SetDeadline 设置截止时间
func (c *RealTCPConn) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t)
}
// SetReadDeadline 设置读截止时间
func (c *RealTCPConn) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}
// SetWriteDeadline 设置写截止时间
func (c *RealTCPConn) SetWriteDeadline(t time.Time) error {
return c.conn.SetWriteDeadline(t)
}
// DialRealTCP 拨号 RealTCP 连接
func DialRealTCP(ctx context.Context, network, addr string, logger *zap.Logger) (net.Conn, error) {
logger.Debug("dialing RealTCP", zap.String("addr", addr))
// 建立 TCP 连接
conn, err := (&net.Dialer{}).DialContext(ctx, network, addr)
if err != nil {
return nil, fmt.Errorf("failed to dial TCP: %w", err)
}
// 包装为 RealTCP 连接
return NewRealTCPConn(conn), nil
}
// ListenRealTCP 监听 RealTCP 端口
func ListenRealTCP(network, addr string, logger *zap.Logger) (net.Listener, error) {
logger.Info("listening RealTCP", zap.String("addr", addr))
// 监听 TCP 端口
listener, err := net.Listen(network, addr)
if err != nil {
return nil, fmt.Errorf("failed to listen TCP: %w", err)
}
return &realTCPListener{
Listener: listener,
logger: logger,
}, nil
}
// realTCPListener RealTCP 监听器
type realTCPListener struct {
net.Listener
logger *zap.Logger
}
// Accept 接受连接并包装为 RealTCPConn
func (l *realTCPListener) Accept() (net.Conn, error) {
conn, err := l.Listener.Accept()
if err != nil {
return nil, err
}
l.logger.Debug("accepted RealTCP connection", zap.String("addr", conn.RemoteAddr().String()))
return NewRealTCPConn(conn), nil
}