add listen_ip

This commit is contained in:
KusakabeSi 2024-01-12 09:31:16 +00:00
parent d78d3335f8
commit a96899a93e
11 changed files with 115 additions and 38 deletions

View File

@ -8,6 +8,7 @@ package conn
import ( import (
"errors" "errors"
"net" "net"
"net/netip"
"strconv" "strconv"
"sync" "sync"
"syscall" "syscall"
@ -57,24 +58,45 @@ func (endpoint *LinuxSocketEndpoint) dst6() *unix.SockaddrInet6 {
type LinuxSocketBind struct { type LinuxSocketBind struct {
// mu guards sock4 and sock6 and the associated fds. // mu guards sock4 and sock6 and the associated fds.
// As long as someone holds mu (read or write), the associated fds are valid. // As long as someone holds mu (read or write), the associated fds are valid.
mu sync.RWMutex mu sync.RWMutex
fwmark uint32 fwmark uint32
sock4 int sock4 int
sock6 int sock6 int
use4 bool use4 bool
use6 bool use6 bool
listen_ip4 [4]byte
listen_ip6 [16]byte
} }
func NewLinuxSocketBind() Bind { return &LinuxSocketBind{sock4: -1, sock6: -1, use4: true, use6: true} } func NewLinuxSocketBind() Bind { return &LinuxSocketBind{sock4: -1, sock6: -1, use4: true, use6: true} }
func NewLinuxSocketBindAf(use4 bool, use6 bool, fwmark uint32) Bind { func NewLinuxSocketBindAf(use4 bool, use6 bool, listen_ip4 [4]byte, listen_ip6 [16]byte, fwmark uint32) Bind {
return &LinuxSocketBind{sock4: -1, sock6: -1, use4: use4, use6: use6, fwmark: fwmark} return &LinuxSocketBind{sock4: -1, sock6: -1, use4: use4, use6: use6, fwmark: fwmark, listen_ip4: listen_ip4, listen_ip6: listen_ip6}
} }
func NewDefaultBind(Af EnabledAf, bindmode string, fwmark uint32) Bind { func NewDefaultBind(Af EnabledAf, bindmode string, fwmark uint32) Bind {
if bindmode == "std" { listen_ip4 := Af.ListenIPv4
return NewStdNetBindAf(Af.IPv4, Af.IPv6, fwmark) listen_ip6 := Af.ListenIPv6
var err error
ListenIP4, _ := netip.ParseAddr("0.0.0.0")
if listen_ip4 != "" {
ListenIP4, err = netip.ParseAddr(listen_ip4)
if err != nil {
ListenIP4, _ = netip.ParseAddr("0.0.0.0")
}
} }
return NewLinuxSocketBindAf(Af.IPv4, Af.IPv6, fwmark)
ListenIP6, _ := netip.ParseAddr("::")
if listen_ip6 != "" {
ListenIP6, err = netip.ParseAddr(listen_ip6)
if err != nil {
ListenIP6, _ = netip.ParseAddr("::")
}
}
if bindmode == "std" {
return NewStdNetBindAf(Af.IPv4, Af.IPv6, ListenIP4.As4(), ListenIP6.As16(), fwmark)
}
return NewLinuxSocketBindAf(Af.IPv4, Af.IPv6, ListenIP4.As4(), ListenIP6.As16(), fwmark)
} }
var _ Endpoint = (*LinuxSocketEndpoint)(nil) var _ Endpoint = (*LinuxSocketEndpoint)(nil)
@ -82,8 +104,8 @@ var _ Bind = (*LinuxSocketBind)(nil)
func (s *LinuxSocketBind) EnabledAf() EnabledAf { func (s *LinuxSocketBind) EnabledAf() EnabledAf {
return EnabledAf{ return EnabledAf{
s.use4, IPv4: s.use4,
s.use6, IPv6: s.use6,
} }
} }
@ -141,7 +163,7 @@ again:
var sock4, sock6 int var sock4, sock6 int
if bind.use6 { if bind.use6 {
// Attempt ipv6 bind, update port if successful. // Attempt ipv6 bind, update port if successful.
sock6, newPort, err = create6(port) sock6, newPort, err = create6(bind.listen_ip6, port)
if err != nil { if err != nil {
if originalPort == 0 && errors.Is(err, syscall.EADDRINUSE) && tries < 100 { if originalPort == 0 && errors.Is(err, syscall.EADDRINUSE) && tries < 100 {
unix.Close(sock4) unix.Close(sock4)
@ -159,7 +181,7 @@ again:
if bind.use4 { if bind.use4 {
// Attempt ipv4 bind, update port if successful. // Attempt ipv4 bind, update port if successful.
sock4, newPort, err = create4(port) sock4, newPort, err = create4(bind.listen_ip4, port)
if err != nil { if err != nil {
if originalPort == 0 && errors.Is(err, syscall.EADDRINUSE) && tries < 100 { if originalPort == 0 && errors.Is(err, syscall.EADDRINUSE) && tries < 100 {
unix.Close(sock6) unix.Close(sock6)
@ -373,7 +395,7 @@ func zoneToUint32(zone string) (uint32, error) {
return uint32(n), err return uint32(n), err
} }
func create4(port uint16) (int, uint16, error) { func create4(listen_ip [4]byte, port uint16) (int, uint16, error) {
// create socket // create socket
@ -388,6 +410,7 @@ func create4(port uint16) (int, uint16, error) {
} }
addr := unix.SockaddrInet4{ addr := unix.SockaddrInet4{
Addr: listen_ip,
Port: int(port), Port: int(port),
} }
@ -417,7 +440,7 @@ func create4(port uint16) (int, uint16, error) {
return fd, uint16(addr.Port), err return fd, uint16(addr.Port), err
} }
func create6(port uint16) (int, uint16, error) { func create6(listen_ip [16]byte, port uint16) (int, uint16, error) {
// create socket // create socket
@ -434,6 +457,7 @@ func create6(port uint16) (int, uint16, error) {
// set sockopts and bind // set sockopts and bind
addr := unix.SockaddrInet6{ addr := unix.SockaddrInet6{
Addr: listen_ip,
Port: int(port), Port: int(port),
} }

View File

@ -8,6 +8,7 @@ package conn
import ( import (
"errors" "errors"
"net" "net"
"net/netip"
"sync" "sync"
"syscall" "syscall"
) )
@ -25,11 +26,13 @@ type StdNetBind struct {
blackhole6 bool blackhole6 bool
use4 bool use4 bool
use6 bool use6 bool
listen_ip4 [4]byte
listen_ip6 [16]byte
} }
func NewStdNetBind() Bind { return &StdNetBind{use4: true, use6: true, fwmark: 0} } func NewStdNetBind() Bind { return &StdNetBind{use4: true, use6: true, fwmark: 0} }
func NewStdNetBindAf(use4 bool, use6 bool, fwmark uint32) Bind { func NewStdNetBindAf(use4 bool, use6 bool, listen_ip4 [4]byte, listen_ip6 [16]byte, fwmark uint32) Bind {
return &StdNetBind{use4: use4, use6: use6, fwmark: fwmark} return &StdNetBind{use4: use4, use6: use6, fwmark: fwmark, listen_ip4: listen_ip4, listen_ip6: listen_ip6}
} }
type StdNetEndpoint net.UDPAddr type StdNetEndpoint net.UDPAddr
@ -46,8 +49,8 @@ func (*StdNetEndpoint) ClearSrc() {}
func (s *StdNetBind) EnabledAf() EnabledAf { func (s *StdNetBind) EnabledAf() EnabledAf {
return EnabledAf{ return EnabledAf{
s.use4, IPv4: s.use4,
s.use6, IPv6: s.use6,
} }
} }
@ -78,8 +81,8 @@ func (e *StdNetEndpoint) SrcToString() string {
return "" return ""
} }
func listenNet(network string, port int) (*net.UDPConn, int, error) { func listenNet(network string, listen_ip net.IP, port int) (*net.UDPConn, int, error) {
conn, err := net.ListenUDP(network, &net.UDPAddr{Port: port}) conn, err := net.ListenUDP(network, &net.UDPAddr{IP: listen_ip, Port: port})
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
@ -114,7 +117,7 @@ again:
var ipv4, ipv6 *net.UDPConn var ipv4, ipv6 *net.UDPConn
if bind.use4 { if bind.use4 {
ipv4, port, err = listenNet("udp4", port) ipv4, port, err = listenNet("udp4", netip.AddrFrom4(bind.listen_ip4).AsSlice(), port)
if uport == 0 && errors.Is(err, syscall.EADDRINUSE) && tries < 100 { if uport == 0 && errors.Is(err, syscall.EADDRINUSE) && tries < 100 {
ipv6.Close() ipv6.Close()
tries++ tries++
@ -128,7 +131,7 @@ again:
if bind.use6 { if bind.use6 {
// Listen on the same port as we're using for ipv4. // Listen on the same port as we're using for ipv4.
ipv6, port, err = listenNet("udp6", port) ipv6, port, err = listenNet("udp6", bind.listen_ip6[:], port)
if uport == 0 && errors.Is(err, syscall.EADDRINUSE) && tries < 100 { if uport == 0 && errors.Is(err, syscall.EADDRINUSE) && tries < 100 {
ipv4.Close() ipv4.Close()
tries++ tries++

View File

@ -48,8 +48,37 @@ type Bind interface {
} }
type EnabledAf struct { type EnabledAf struct {
IPv4 bool `yaml:"IPv4"` IPv4 bool `yaml:"IPv4"`
IPv6 bool `yaml:"IPv6"` IPv6 bool `yaml:"IPv6"`
ListenIPv4 string `yaml:"ListenIPv4"`
ListenIPv6 string `yaml:"ListenIPv6"`
}
func (self EnabledAf) Disalbed2Enabled() EnabledAf {
return EnabledAf{
!self.IPv4,
!self.IPv6,
self.ListenIPv4,
self.ListenIPv6,
}
}
func (self EnabledAf) GetOnly4() EnabledAf {
return EnabledAf{
self.IPv4,
false,
self.ListenIPv4,
"",
}
}
func (self EnabledAf) GetOnly6() EnabledAf {
return EnabledAf{
false,
self.IPv6,
"",
self.ListenIPv6,
}
} }
var EnabledAf4 = EnabledAf{ var EnabledAf4 = EnabledAf{

View File

@ -18,9 +18,12 @@ DefaultTTL: 200
L2FIBTimeout: 3600 L2FIBTimeout: 3600
PrivKey: lyQLML+TbAZvrJpa25ARTAfMvHVQa/a1n3Wcwo7nkDU= PrivKey: lyQLML+TbAZvrJpa25ARTAfMvHVQa/a1n3Wcwo7nkDU=
ListenPort: 3001 ListenPort: 3001
FwMark: 0
DisabledAf: DisabledAf:
IPv4: false IPv4: false
IPv6: false IPv6: false
ListenIPv4: ""
ListenIPv6: ""
AfPrefer: 4 AfPrefer: 4
LogLevel: LogLevel:
LogLevel: error LogLevel: error

View File

@ -18,9 +18,12 @@ DefaultTTL: 200
L2FIBTimeout: 3600 L2FIBTimeout: 3600
PrivKey: r6vMkwreEkbpXoaHgdecPuWhaVK4qWlKazgQbYPDSQ4= PrivKey: r6vMkwreEkbpXoaHgdecPuWhaVK4qWlKazgQbYPDSQ4=
ListenPort: 3002 ListenPort: 3002
FwMark: 0
DisabledAf: DisabledAf:
IPv4: false IPv4: false
IPv6: false IPv6: false
ListenIPv4: ""
ListenIPv6: ""
AfPrefer: 4 AfPrefer: 4
LogLevel: LogLevel:
LogLevel: error LogLevel: error

View File

@ -18,9 +18,12 @@ DefaultTTL: 200
L2FIBTimeout: 3600 L2FIBTimeout: 3600
PrivKey: U68wDkoic4xviKbOed9EBykI/wgpfpHGmc8N4ML5spE= PrivKey: U68wDkoic4xviKbOed9EBykI/wgpfpHGmc8N4ML5spE=
ListenPort: 0 ListenPort: 0
FwMark: 0
DisabledAf: DisabledAf:
IPv4: false IPv4: false
IPv6: false IPv6: false
ListenIPv4: ""
ListenIPv6: ""
AfPrefer: 4 AfPrefer: 4
LogLevel: LogLevel:
LogLevel: error LogLevel: error

View File

@ -5,6 +5,12 @@ PrivKeyV6: xUJ4yaVl/O//PRS24UFMNXgmeF/rhykroCxdJrljFgE=
ListenPort: 3456 ListenPort: 3456
ListenPort_EdgeAPI: "3456" ListenPort_EdgeAPI: "3456"
ListenPort_ManageAPI: "3456" ListenPort_ManageAPI: "3456"
FwMark: 0
DisabledAf:
IPv4: false
IPv6: false
ListenIPv4: ""
ListenIPv6: ""
API_Prefix: /eg_net/eg_api API_Prefix: /eg_net/eg_api
RePushConfigInterval: 30 RePushConfigInterval: 30
HttpPostInterval: 50 HttpPostInterval: 50

View File

@ -120,10 +120,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
} }
graph.SetNHTable(econfig.NextHopTable) graph.SetNHTable(econfig.NextHopTable)
EnabledAf := conn.EnabledAf{ EnabledAf := econfig.DisableAf.Disalbed2Enabled()
IPv4: !econfig.DisableAf.IPv4,
IPv6: !econfig.DisableAf.IPv6,
}
the_device := device.NewDevice(thetap, econfig.NodeID, conn.NewDefaultBind(EnabledAf, bindmode, econfig.FwMark), logger, graph, false, configPath, &econfig, nil, nil, Version) the_device := device.NewDevice(thetap, econfig.NodeID, conn.NewDefaultBind(EnabledAf, bindmode, econfig.FwMark), logger, graph, false, configPath, &econfig, nil, nil, Version)
defer the_device.Close() defer the_device.Close()
@ -181,7 +178,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
StaticSuper = false StaticSuper = false
} }
} }
err = peer.SetEndpointFromConnURL(econfig.DynamicRoute.SuperNode.EndpointV4, conn.EnabledAf4, 0, StaticSuper) err = peer.SetEndpointFromConnURL(econfig.DynamicRoute.SuperNode.EndpointV4, EnabledAf.GetOnly4(), 0, StaticSuper)
if err != nil { if err != nil {
logger.Errorf("Failed to set endpoint for supernode v4 %v: %v", econfig.DynamicRoute.SuperNode.EndpointV4, err) logger.Errorf("Failed to set endpoint for supernode v4 %v: %v", econfig.DynamicRoute.SuperNode.EndpointV4, err)
S4 = false S4 = false
@ -211,7 +208,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
StaticSuper = false StaticSuper = false
} }
} }
err = peer.SetEndpointFromConnURL(econfig.DynamicRoute.SuperNode.EndpointV6, conn.EnabledAf6, 0, StaticSuper) err = peer.SetEndpointFromConnURL(econfig.DynamicRoute.SuperNode.EndpointV6, EnabledAf.GetOnly6(), 0, StaticSuper)
if err != nil { if err != nil {
logger.Errorf("Failed to set endpoint for supernode v6 %v: %v", econfig.DynamicRoute.SuperNode.EndpointV6, err) logger.Errorf("Failed to set endpoint for supernode v6 %v: %v", econfig.DynamicRoute.SuperNode.EndpointV6, err)
S6 = false S6 = false

View File

@ -121,6 +121,14 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
fmt.Sprintf("(%s) ", NodeName+"_v6"), fmt.Sprintf("(%s) ", NodeName+"_v6"),
) )
EnabledAf := sconfig.DisableAf.Disalbed2Enabled()
if !EnabledAf.IPv4 {
sconfig.PrivKeyV4 = ""
}
if !EnabledAf.IPv6 {
sconfig.PrivKeyV6 = ""
}
httpobj.http_sconfig_path = configPath httpobj.http_sconfig_path = configPath
httpobj.http_PeerState = make(map[string]*PeerState) httpobj.http_PeerState = make(map[string]*PeerState)
httpobj.http_PeerIPs = make(map[string]*HttpPeerLocalIP) httpobj.http_PeerIPs = make(map[string]*HttpPeerLocalIP)
@ -144,10 +152,10 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
} }
} }
thetap4, _ := tap.CreateDummyTAP() thetap4, _ := tap.CreateDummyTAP()
httpobj.http_device4 = device.NewDevice(thetap4, mtypes.NodeID_SuperNode, conn.NewDefaultBind(conn.EnabledAf4, bindmode, sconfig.FwMark), logger4, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version) httpobj.http_device4 = device.NewDevice(thetap4, mtypes.NodeID_SuperNode, conn.NewDefaultBind(EnabledAf.GetOnly4(), bindmode, sconfig.FwMark), logger4, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version)
defer httpobj.http_device4.Close() defer httpobj.http_device4.Close()
thetap6, _ := tap.CreateDummyTAP() thetap6, _ := tap.CreateDummyTAP()
httpobj.http_device6 = device.NewDevice(thetap6, mtypes.NodeID_SuperNode, conn.NewDefaultBind(conn.EnabledAf6, bindmode, sconfig.FwMark), logger6, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version) httpobj.http_device6 = device.NewDevice(thetap6, mtypes.NodeID_SuperNode, conn.NewDefaultBind(EnabledAf.GetOnly6(), bindmode, sconfig.FwMark), logger6, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version)
defer httpobj.http_device6.Close() defer httpobj.http_device6.Close()
if sconfig.PrivKeyV4 != "" { if sconfig.PrivKeyV4 != "" {
pk4, err := device.Str2PriKey(sconfig.PrivKeyV4) pk4, err := device.Str2PriKey(sconfig.PrivKeyV4)

View File

@ -23,12 +23,12 @@ type EdgeConfig struct {
Interface InterfaceConf `yaml:"Interface"` Interface InterfaceConf `yaml:"Interface"`
NodeID Vertex `yaml:"NodeID"` NodeID Vertex `yaml:"NodeID"`
NodeName string `yaml:"NodeName"` NodeName string `yaml:"NodeName"`
FwMark uint32 `yaml:"FwMark"`
PostScript string `yaml:"PostScript"` PostScript string `yaml:"PostScript"`
DefaultTTL uint8 `yaml:"DefaultTTL"` DefaultTTL uint8 `yaml:"DefaultTTL"`
L2FIBTimeout float64 `yaml:"L2FIBTimeout"` L2FIBTimeout float64 `yaml:"L2FIBTimeout"`
PrivKey string `yaml:"PrivKey"` PrivKey string `yaml:"PrivKey"`
ListenPort int `yaml:"ListenPort"` ListenPort int `yaml:"ListenPort"`
FwMark uint32 `yaml:"FwMark"`
DisableAf conn.EnabledAf `yaml:"DisabledAf"` DisableAf conn.EnabledAf `yaml:"DisabledAf"`
AfPrefer int `yaml:"AfPrefer"` AfPrefer int `yaml:"AfPrefer"`
LogLevel LoggerInfo `yaml:"LogLevel"` LogLevel LoggerInfo `yaml:"LogLevel"`
@ -40,13 +40,14 @@ type EdgeConfig struct {
type SuperConfig struct { type SuperConfig struct {
NodeName string `yaml:"NodeName"` NodeName string `yaml:"NodeName"`
FwMark uint32 `yaml:"FwMark"`
PostScript string `yaml:"PostScript"` PostScript string `yaml:"PostScript"`
PrivKeyV4 string `yaml:"PrivKeyV4"` PrivKeyV4 string `yaml:"PrivKeyV4"`
PrivKeyV6 string `yaml:"PrivKeyV6"` PrivKeyV6 string `yaml:"PrivKeyV6"`
ListenPort int `yaml:"ListenPort"` ListenPort int `yaml:"ListenPort"`
ListenPort_EdgeAPI string `yaml:"ListenPort_EdgeAPI"` ListenPort_EdgeAPI string `yaml:"ListenPort_EdgeAPI"`
ListenPort_ManageAPI string `yaml:"ListenPort_ManageAPI"` ListenPort_ManageAPI string `yaml:"ListenPort_ManageAPI"`
FwMark uint32 `yaml:"FwMark"`
DisableAf conn.EnabledAf `yaml:"DisabledAf"`
API_Prefix string `yaml:"API_Prefix"` API_Prefix string `yaml:"API_Prefix"`
RePushConfigInterval float64 `yaml:"RePushConfigInterval"` RePushConfigInterval float64 `yaml:"RePushConfigInterval"`
HttpPostInterval float64 `yaml:"HttpPostInterval"` HttpPostInterval float64 `yaml:"HttpPostInterval"`

View File

@ -1,3 +1,3 @@
package main package main
var Version = "v0.3.5-f2" var Version = "v0.3.5-f4"