diff --git a/cmd/config.go b/cmd/config.go index 38ff2b4..abb2339 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -63,10 +63,10 @@ type serverConfig struct { User string `json:"user"` Password string `json:"password"` } `json:"socks5_outbound"` - SocketConfig struct { - BindAddress string `json:"bind_address"` - BindToDevice string `json:"bind_to_device"` - } `json:"socket_config"` + BindOutbound struct { + Address string `json:"address"` + Device string `json:"device"` + } `json:"bind_outbound"` } func (c *serverConfig) Speed() (uint64, uint64, error) { diff --git a/cmd/server.go b/cmd/server.go index 0c42297..5334ac2 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -164,32 +164,26 @@ func server(config *serverConfig) { } transport.DefaultServerTransport.SOCKS5Client = ob } - // socket settings - if config.SocketConfig.BindToDevice != "" { - iface, err := net.InterfaceByName(config.SocketConfig.BindToDevice) + // Bind outbound + if config.BindOutbound.Device != "" { + iface, err := net.InterfaceByName(config.BindOutbound.Device) if err != nil { logrus.WithFields(logrus.Fields{ "error": err, - }).Fatal("Failed to get bind_to_device") + }).Fatal("Failed to find the interface") } - transport.DefaultServerTransport.Intf = iface + transport.DefaultServerTransport.LocalUDPIntf = iface sockopt.BindDialer(transport.DefaultServerTransport.Dialer, iface) } - if config.SocketConfig.BindAddress != "" { - ip := net.ParseIP(config.SocketConfig.BindAddress) + if config.BindOutbound.Address != "" { + ip := net.ParseIP(config.BindOutbound.Address) if ip == nil { logrus.WithFields(logrus.Fields{ "error": err, - }).Fatal("Failed to parse bind_address") - } - transport.DefaultServerTransport.Dialer.LocalAddr = &net.TCPAddr{ - IP: ip, - Port: 0, - } - transport.DefaultServerTransport.LocalAddrUDP = &net.UDPAddr{ - IP: ip, - Port: 0, + }).Fatal("Failed to parse the address") } + transport.DefaultServerTransport.Dialer.LocalAddr = &net.TCPAddr{IP: ip} + transport.DefaultServerTransport.LocalUDPAddr = &net.UDPAddr{IP: ip} } // ACL var aclEngine *acl.Engine diff --git a/pkg/sockopt/sockopt.go b/pkg/sockopt/sockopt.go index d33826b..db97810 100644 --- a/pkg/sockopt/sockopt.go +++ b/pkg/sockopt/sockopt.go @@ -5,7 +5,7 @@ import ( "syscall" ) -//https://github.com/v2fly/v2ray-core/blob/4e247840821f3dd326722d4db02ee3c237074fc2/transport/internet/config.pb.go#L420-L426 +// https://github.com/v2fly/v2ray-core/blob/4e247840821f3dd326722d4db02ee3c237074fc2/transport/internet/config.pb.go#L420-L426 func BindDialer(d *net.Dialer, intf *net.Interface) { d.Control = func(network, address string, c syscall.RawConn) error { diff --git a/pkg/sockopt/sockopt_linux.go b/pkg/sockopt/sockopt_linux.go index 1fa795f..e7df7a8 100644 --- a/pkg/sockopt/sockopt_linux.go +++ b/pkg/sockopt/sockopt_linux.go @@ -8,9 +8,15 @@ import ( ) func bindRawConn(network string, c syscall.RawConn, bindIface *net.Interface) error { - return c.Control(func(fd uintptr) { + var err1, err2 error + err1 = c.Control(func(fd uintptr) { if bindIface != nil { - unix.BindToDevice(int(fd), bindIface.Name) + err2 = unix.BindToDevice(int(fd), bindIface.Name) } }) + if err1 != nil { + return err1 + } else { + return err2 + } } diff --git a/pkg/sockopt/sockopt_others.go b/pkg/sockopt/sockopt_others.go index 1694d53..af0a107 100644 --- a/pkg/sockopt/sockopt_others.go +++ b/pkg/sockopt/sockopt_others.go @@ -3,8 +3,11 @@ package sockopt import ( + "errors" "net" "syscall" ) -func bindRawConn(network string, c syscall.RawConn, bindIface *net.Interface) error { return nil } +func bindRawConn(network string, c syscall.RawConn, bindIface *net.Interface) error { + return errors.New("binding interface is not supported on the current system") +} diff --git a/pkg/transport/server.go b/pkg/transport/server.go index 8e03379..0805f1a 100644 --- a/pkg/transport/server.go +++ b/pkg/transport/server.go @@ -21,8 +21,8 @@ type ServerTransport struct { PrefEnabled bool PrefIPv6 bool PrefExclusive bool - LocalAddrUDP *net.UDPAddr - Intf *net.Interface + LocalUDPAddr *net.UDPAddr + LocalUDPIntf *net.Interface } // AddrEx is like net.TCPAddr or net.UDPAddr, but with additional domain information for SOCKS5. @@ -167,12 +167,12 @@ func (st *ServerTransport) ListenUDP() (PUDPConn, error) { if st.SOCKS5Client != nil { return st.SOCKS5Client.ListenUDP() } else { - conn, err := net.ListenUDP("udp", st.LocalAddrUDP) + conn, err := net.ListenUDP("udp", st.LocalUDPAddr) if err != nil { return nil, err } - if st.Intf != nil { - err = sockopt.BindUDPConn("udp", conn, st.Intf) + if st.LocalUDPIntf != nil { + err = sockopt.BindUDPConn("udp", conn, st.LocalUDPIntf) if err != nil { conn.Close() return nil, err