Hunter0x7c7
2022-08-11 a82f9cb69f63aaeba40c024960deda7d75b9fece
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package tcp
 
import (
    "context"
    gotls "crypto/tls"
    "strings"
    "time"
 
    "github.com/v2fly/v2ray-core/v5/common"
    "github.com/v2fly/v2ray-core/v5/common/net"
    "github.com/v2fly/v2ray-core/v5/common/serial"
    "github.com/v2fly/v2ray-core/v5/common/session"
    "github.com/v2fly/v2ray-core/v5/transport/internet"
    "github.com/v2fly/v2ray-core/v5/transport/internet/tls"
)
 
// Listener is an internet.Listener that listens for TCP connections.
type Listener struct {
    listener   net.Listener
    tlsConfig  *gotls.Config
    authConfig internet.ConnectionAuthenticator
    config     *Config
    addConn    internet.ConnHandler
    locker     *internet.FileLocker // for unix domain socket
}
 
// ListenTCP creates a new Listener based on configurations.
func ListenTCP(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {
    l := &Listener{
        addConn: handler,
    }
    tcpSettings := streamSettings.ProtocolSettings.(*Config)
    l.config = tcpSettings
    if l.config != nil {
        if streamSettings.SocketSettings == nil {
            streamSettings.SocketSettings = &internet.SocketConfig{}
        }
        streamSettings.SocketSettings.AcceptProxyProtocol = l.config.AcceptProxyProtocol
    }
    var listener net.Listener
    var err error
    if address.Family().IsDomain() {
        listener, err = internet.ListenSystem(ctx, &net.UnixAddr{
            Name: address.Domain(),
            Net:  "unix",
        }, streamSettings.SocketSettings)
        if err != nil {
            return nil, newError("failed to listen Unix Domain Socket on ", address).Base(err)
        }
        newError("listening Unix Domain Socket on ", address).WriteToLog(session.ExportIDToError(ctx))
        locker := ctx.Value(address.Domain())
        if locker != nil {
            l.locker = locker.(*internet.FileLocker)
        }
    } else {
        listener, err = internet.ListenSystem(ctx, &net.TCPAddr{
            IP:   address.IP(),
            Port: int(port),
        }, streamSettings.SocketSettings)
        if err != nil {
            return nil, newError("failed to listen TCP on ", address, ":", port).Base(err)
        }
        newError("listening TCP on ", address, ":", port).WriteToLog(session.ExportIDToError(ctx))
    }
 
    if streamSettings.SocketSettings != nil && streamSettings.SocketSettings.AcceptProxyProtocol {
        newError("accepting PROXY protocol").AtWarning().WriteToLog(session.ExportIDToError(ctx))
    }
 
    l.listener = listener
 
    if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
        l.tlsConfig = config.GetTLSConfig()
    }
 
    if tcpSettings.HeaderSettings != nil {
        headerConfig, err := serial.GetInstanceOf(tcpSettings.HeaderSettings)
        if err != nil {
            return nil, newError("invalid header settings").Base(err).AtError()
        }
        auth, err := internet.CreateConnectionAuthenticator(headerConfig)
        if err != nil {
            return nil, newError("invalid header settings.").Base(err).AtError()
        }
        l.authConfig = auth
    }
 
    go l.keepAccepting()
    return l, nil
}
 
func (v *Listener) keepAccepting() {
    for {
        conn, err := v.listener.Accept()
        if err != nil {
            errStr := err.Error()
            if strings.Contains(errStr, "closed") {
                break
            }
            newError("failed to accepted raw connections").Base(err).AtWarning().WriteToLog()
            if strings.Contains(errStr, "too many") {
                time.Sleep(time.Millisecond * 500)
            }
            continue
        }
 
        if v.tlsConfig != nil {
            conn = tls.Server(conn, v.tlsConfig)
        }
        if v.authConfig != nil {
            conn = v.authConfig.Server(conn)
        }
 
        v.addConn(internet.Connection(conn))
    }
}
 
// Addr implements internet.Listener.Addr.
func (v *Listener) Addr() net.Addr {
    return v.listener.Addr()
}
 
// Close implements internet.Listener.Close.
func (v *Listener) Close() error {
    if v.locker != nil {
        v.locker.Release()
    }
    return v.listener.Close()
}
 
func init() {
    common.Must(internet.RegisterTransportListener(protocolName, ListenTCP))
}