Skip to content

Commit 05f8de1

Browse files
committed
allow custom controller function
1 parent 0f63be6 commit 05f8de1

File tree

2 files changed

+67
-17
lines changed

2 files changed

+67
-17
lines changed

transport/internet/system_listener.go

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,57 @@ var (
1212
effectiveListener = DefaultListener{}
1313
)
1414

15-
type DefaultListener struct{}
15+
type controller func(network, address string, fd uintptr) error
1616

17-
func (*DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.Listener, error) {
18-
var lc net.ListenConfig
17+
type DefaultListener struct {
18+
contollers []controller
19+
}
1920

20-
if sockopt != nil {
21-
lc.Control = func(network, address string, c syscall.RawConn) error {
22-
return c.Control(func(fd uintptr) {
21+
func getControlFunc(ctx context.Context, sockopt *SocketConfig, contollers []controller) func(network, address string, c syscall.RawConn) error {
22+
return func(network, address string, c syscall.RawConn) error {
23+
return c.Control(func(fd uintptr) {
24+
if sockopt != nil {
2325
if err := applyInboundSocketOptions(network, fd, sockopt); err != nil {
2426
newError("failed to apply socket options to incoming connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
2527
}
26-
})
27-
}
28+
}
29+
30+
for _, controller := range contollers {
31+
if err := controller(network, address, fd); err != nil {
32+
newError("failed to apply external controller").Base(err).WriteToLog(session.ExportIDToError(ctx))
33+
}
34+
}
35+
})
36+
}
37+
}
38+
39+
func (dl *DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.Listener, error) {
40+
var lc net.ListenConfig
41+
42+
if sockopt != nil || len(dl.contollers) > 0 {
43+
lc.Control = getControlFunc(ctx, sockopt, dl.contollers)
2844
}
2945

3046
return lc.Listen(ctx, addr.Network(), addr.String())
3147
}
3248

33-
func (*DefaultListener) ListenPacket(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.PacketConn, error) {
49+
func (dl *DefaultListener) ListenPacket(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.PacketConn, error) {
3450
var lc net.ListenConfig
3551

36-
if sockopt != nil {
37-
lc.Control = func(network, address string, c syscall.RawConn) error {
38-
return c.Control(func(fd uintptr) {
39-
if err := applyInboundSocketOptions(network, fd, sockopt); err != nil {
40-
newError("failed to apply socket options to incoming connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
41-
}
42-
})
43-
}
52+
if sockopt != nil || len(dl.contollers) > 0 {
53+
lc.Control = getControlFunc(ctx, sockopt, dl.contollers)
4454
}
4555

4656
return lc.ListenPacket(ctx, addr.Network(), addr.String())
4757
}
58+
59+
// RegisterListenerController adds a controller to the effective system listener.
60+
// The controller can be used to operate on file descriptors before they are put into use.
61+
func RegisterListenerController(controller func(network, address string, fd uintptr) error) error {
62+
if controller == nil {
63+
return newError("nil listener controller")
64+
}
65+
66+
effectiveListener.contollers = append(effectiveListener.contollers, controller)
67+
return nil
68+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package internet_test
2+
3+
import (
4+
"context"
5+
"net"
6+
"testing"
7+
8+
"v2ray.com/core/common"
9+
"v2ray.com/core/transport/internet"
10+
)
11+
12+
func TestRegisterListenerController(t *testing.T) {
13+
var gotFd uintptr
14+
15+
common.Must(internet.RegisterListenerController(func(network string, addr string, fd uintptr) error {
16+
gotFd = fd
17+
return nil
18+
}))
19+
20+
conn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{
21+
IP: net.IPv4zero,
22+
}, nil)
23+
common.Must(err)
24+
common.Must(conn.Close())
25+
26+
if gotFd == 0 {
27+
t.Error("expected none-zero fd, but actually 0")
28+
}
29+
}

0 commit comments

Comments
 (0)