-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlistener_linux.go
71 lines (56 loc) · 2.25 KB
/
listener_linux.go
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
// Copyright (c) 2024 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
//go:build linux
package mitm
import (
"fmt"
"net"
"syscall"
)
func ListenTCPTProxy(network string, laddr *net.TCPAddr) (*net.TCPListener, error) {
l, err := net.ListenTCP(network, laddr)
if err != nil {
return nil, err
}
fileDescriptorSource, err := l.File()
if err != nil {
return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("get file descriptor: %w", err)}
}
defer fileDescriptorSource.Close()
fd := int(fileDescriptorSource.Fd())
if err = syscall.SetsockoptInt(fd, syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {
return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("set IP_TRANSPARENT: %w", err)}
}
if err = syscall.SetNonblock(fd, true); err != nil {
return nil, &net.OpError{Op: "listen", Err: fmt.Errorf("set O_NONBLOCK: %w", err)}
}
return l, nil
}
func ListenUDPTProxy(network string, laddr *net.UDPAddr) (*net.UDPConn, error) {
l, err := net.ListenUDP(network, laddr)
if err != nil {
return nil, err
}
fileDescriptorSource, err := l.File()
if err != nil {
return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("get file descriptor: %w", err)}
}
defer fileDescriptorSource.Close()
fd := int(fileDescriptorSource.Fd())
if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
return nil, &net.OpError{Op: "listen", Err: fmt.Errorf("set SO_REUSEADDR: %w", err)}
}
if err = syscall.SetsockoptInt(fd, syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {
return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("set IP_TRANSPARENT: %w", err)}
}
if err = syscall.SetsockoptInt(fd, syscall.SOL_IP, syscall.IP_RECVORIGDSTADDR, 1); err != nil {
return nil, &net.OpError{Op: "listen", Net: network, Source: nil, Addr: laddr, Err: fmt.Errorf("set IP_RECVORIGDSTADDR: %w", err)}
}
if err = syscall.SetNonblock(fd, true); err != nil {
return nil, &net.OpError{Op: "listen", Err: fmt.Errorf("set O_NONBLOCK: %w", err)}
}
return l, nil
}