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"
@ -63,18 +64,39 @@ type LinuxSocketBind struct {
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

@ -50,6 +50,35 @@ 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"