mirror of
https://github.com/apernet/hysteria.git
synced 2025-04-03 20:47:38 +03:00
57 lines
1.1 KiB
Go
57 lines
1.1 KiB
Go
package outbounds
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
"syscall"
|
|
)
|
|
|
|
func dialerBindToDevice(dialer *net.Dialer, deviceName string) error {
|
|
if err := verifyDeviceName(deviceName); err != nil {
|
|
return err
|
|
}
|
|
|
|
originControl := dialer.Control
|
|
dialer.Control = func(network, address string, c syscall.RawConn) error {
|
|
if originControl != nil {
|
|
// Chaining other control function
|
|
err := originControl(network, address, c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
var errBind error
|
|
err := c.Control(func(fd uintptr) {
|
|
errBind = syscall.BindToDevice(int(fd), deviceName)
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return errBind
|
|
}
|
|
return 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
|
|
}
|