Files
.github
app
core
extras
auth
correctnet
masq
obfs
outbounds
acl
.mockery.yaml
acl.go
acl_test.go
dns_https.go
dns_standard.go
dns_system.go
interface.go
interface_test.go
mock_PluggableOutbound.go
mock_UDPConn.go
ob_direct.go
ob_direct_linux.go
ob_direct_others.go
ob_http.go
ob_socks5.go
utils.go
utils_test.go
trafficlogger
transport
go.mod
go.sum
media-kit
scripts
.gitignore
CHANGELOG.md
Dockerfile
LICENSE.md
PROTOCOL.md
README.md
go.work
go.work.sum
hyperbole.py
logo.svg
platforms.txt
hysteria-dev/extras/outbounds/ob_direct_linux.go
2023-07-28 13:44:33 -07:00

58 lines
1.3 KiB
Go

package outbounds
import (
"errors"
"net"
"syscall"
)
// NewDirectOutboundBindToDevice creates a new directOutbound with the given mode,
// and binds to the given device. Only works on Linux.
func NewDirectOutboundBindToDevice(mode DirectOutboundMode, deviceName string) (PluggableOutbound, error) {
if err := verifyDeviceName(deviceName); err != nil {
return nil, err
}
d := &net.Dialer{
Timeout: defaultDialerTimeout,
Control: func(network, address string, c syscall.RawConn) error {
var errBind error
err := c.Control(func(fd uintptr) {
errBind = syscall.BindToDevice(int(fd), deviceName)
})
if err != nil {
return err
}
return errBind
},
}
return &directOutbound{
Mode: mode,
Dialer4: d,
Dialer6: d,
DeviceName: deviceName,
}, nil
}
func verifyDeviceName(deviceName string) error {
if deviceName == "" {
return errors.New("device name cannot be empty")
}
_, err := net.InterfaceByName(deviceName)
return err
}
func udpConnBindToDevice(conn *net.UDPConn, deviceName string) error {
sc, err := conn.SyscallConn()
if err != nil {
return err
}
var errBind error
err = sc.Control(func(fd uintptr) {
errBind = syscall.BindToDevice(int(fd), deviceName)
})
if err != nil {
return err
}
return errBind
}