Hunter0x7c7
2022-08-11 b8230139fb40edea387617b6accd8371e37eda58
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package tcp
 
import (
    "context"
    "fmt"
    "io"
 
    "github.com/v2fly/v2ray-core/v5/common/buf"
    "github.com/v2fly/v2ray-core/v5/common/net"
    "github.com/v2fly/v2ray-core/v5/common/task"
    "github.com/v2fly/v2ray-core/v5/transport/internet"
    "github.com/v2fly/v2ray-core/v5/transport/pipe"
)
 
type Server struct {
    Port         net.Port
    MsgProcessor func(msg []byte) []byte
    ShouldClose  bool
    SendFirst    []byte
    Listen       net.Address
    listener     net.Listener
}
 
func (server *Server) Start() (net.Destination, error) {
    return server.StartContext(context.Background(), nil)
}
 
func (server *Server) StartContext(ctx context.Context, sockopt *internet.SocketConfig) (net.Destination, error) {
    listenerAddr := server.Listen
    if listenerAddr == nil {
        listenerAddr = net.LocalHostIP
    }
    listener, err := internet.ListenSystem(ctx, &net.TCPAddr{
        IP:   listenerAddr.IP(),
        Port: int(server.Port),
    }, sockopt)
    if err != nil {
        return net.Destination{}, err
    }
 
    localAddr := listener.Addr().(*net.TCPAddr)
    server.Port = net.Port(localAddr.Port)
    server.listener = listener
    go server.acceptConnections(listener.(*net.TCPListener))
 
    return net.TCPDestination(net.IPAddress(localAddr.IP), net.Port(localAddr.Port)), nil
}
 
func (server *Server) acceptConnections(listener *net.TCPListener) {
    for {
        conn, err := listener.Accept()
        if err != nil {
            fmt.Printf("Failed accept TCP connection: %v\n", err)
            return
        }
 
        go server.handleConnection(conn)
    }
}
 
func (server *Server) handleConnection(conn net.Conn) {
    if len(server.SendFirst) > 0 {
        conn.Write(server.SendFirst)
    }
 
    pReader, pWriter := pipe.New(pipe.WithoutSizeLimit())
    err := task.Run(context.Background(), func() error {
        defer pWriter.Close()
 
        for {
            b := buf.New()
            if _, err := b.ReadFrom(conn); err != nil {
                if err == io.EOF {
                    return nil
                }
                return err
            }
            copy(b.Bytes(), server.MsgProcessor(b.Bytes()))
            if err := pWriter.WriteMultiBuffer(buf.MultiBuffer{b}); err != nil {
                return err
            }
        }
    }, func() error {
        defer pReader.Interrupt()
 
        w := buf.NewWriter(conn)
        for {
            mb, err := pReader.ReadMultiBuffer()
            if err != nil {
                if err == io.EOF {
                    return nil
                }
                return err
            }
            if err := w.WriteMultiBuffer(mb); err != nil {
                return err
            }
        }
    })
    if err != nil {
        fmt.Println("failed to transfer data: ", err.Error())
    }
 
    conn.Close()
}
 
func (server *Server) Close() error {
    return server.listener.Close()
}