diff --git a/internal/context/ausf_context_init.go b/internal/context/ausf_context_init.go index 575a04f..5837018 100644 --- a/internal/context/ausf_context_init.go +++ b/internal/context/ausf_context_init.go @@ -3,10 +3,11 @@ package context import ( "fmt" "os" - "strconv" + "net/netip" "github.com/google/uuid" + "github.com/free5gc/ausf/internal/net_util" "github.com/free5gc/ausf/internal/logger" "github.com/free5gc/ausf/pkg/factory" "github.com/free5gc/openapi/models" @@ -23,36 +24,46 @@ func InitAusfContext(context *AUSFContext) { context.GroupID = configuration.GroupId context.NrfUri = configuration.NrfUri context.NrfCertPem = configuration.NrfCertPem - context.UriScheme = models.UriScheme(configuration.Sbi.Scheme) // default uri scheme - context.RegisterIPv4 = factory.AusfSbiDefaultIPv4 // default localhost - context.SBIPort = factory.AusfSbiDefaultPort // default port - if sbi != nil { - if sbi.RegisterIPv4 != "" { - context.RegisterIPv4 = sbi.RegisterIPv4 - } - if sbi.Port != 0 { - context.SBIPort = sbi.Port - } - - if sbi.Scheme == "https" { - context.UriScheme = models.UriScheme_HTTPS - } else { - context.UriScheme = models.UriScheme_HTTP - } - - context.BindingIPv4 = os.Getenv(sbi.BindingIPv4) - if context.BindingIPv4 != "" { - logger.InitLog.Info("Parsing ServerIPv4 address from ENV Variable.") - } else { - context.BindingIPv4 = sbi.BindingIPv4 - if context.BindingIPv4 == "" { - logger.InitLog.Warn("Error parsing ServerIPv4 address as string. Using the 0.0.0.0 address as default.") - context.BindingIPv4 = "0.0.0.0" - } - } + + if sbi.RegisterIP != "" { + context.RegisterIP = sbi.RegisterIP + } else if sbi.RegisterIPv4 != "" { + context.RegisterIP = sbi.RegisterIPv4 + } else { + context.RegisterIP = factory.AusfSbiDefaultIPv4 // default uri scheme + } + + if sbi.Port != 0 { + context.SBIPort = sbi.Port + } else { + context.SBIPort = factory.AusfSbiDefaultPort // default port } - context.Url = string(context.UriScheme) + "://" + context.RegisterIPv4 + ":" + strconv.Itoa(context.SBIPort) + if sbi.Scheme == "https" { + context.UriScheme = models.UriScheme_HTTPS + } else { + context.UriScheme = models.UriScheme_HTTP + } + + if bindingIP := os.Getenv(sbi.BindingIP); bindingIP != "" { + context.BindingIP = bindingIP; + logger.InitLog.Info("Parsing ServerIP address from ENV Variable.") + } else if bindingIP := sbi.BindingIP; bindingIP != "" { + context.BindingIP = bindingIP; + } else if bindingIPv4 := os.Getenv(sbi.BindingIPv4); bindingIPv4 != "" { + context.BindingIP = bindingIPv4; + logger.InitLog.Info("Parsing ServerIPv4 address from ENV Variable.") + } else if bindingIPv4 := sbi.BindingIPv4; bindingIPv4 != "" { + context.BindingIP = bindingIPv4; + } else { + logger.InitLog.Warn("Error parsing ServerIPv4 address as string. Using the 0.0.0.0 address as default.") + context.BindingIP = "0.0.0.0" + } + + sbiRegisterIp := net_util.RegisterAddr(context.RegisterIP) + sbiPort := uint16(context.SBIPort) + + context.Url = string(context.UriScheme) + "://" + netip.AddrPortFrom(sbiRegisterIp, sbiPort).String() context.PlmnList = append(context.PlmnList, configuration.PlmnSupportList...) // context.NfService @@ -74,8 +85,15 @@ func AddNfServices(serviceMap *map[models.ServiceName]models.NfService, config * nfService.ServiceName = models.ServiceName_NAUSF_AUTH var ipEndPoint models.IpEndPoint - ipEndPoint.Ipv4Address = context.RegisterIPv4 ipEndPoint.Port = int32(context.SBIPort) + + registerAddr := net_util.RegisterAddr(context.RegisterIP) + if registerAddr.Is6() { + ipEndPoint.Ipv6Address = context.RegisterIP + } else if registerAddr.Is4() { + ipEndPoint.Ipv4Address = context.RegisterIP + } + ipEndPoints = append(ipEndPoints, ipEndPoint) var nfServiceVersion models.NfServiceVersion diff --git a/internal/context/context.go b/internal/context/context.go index 017ac74..d454383 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -16,8 +16,8 @@ type AUSFContext struct { NfId string GroupID string SBIPort int - RegisterIPv4 string - BindingIPv4 string + RegisterIP string + BindingIP string Url string UriScheme models.UriScheme NrfUri string diff --git a/internal/net_util/net_util.go b/internal/net_util/net_util.go new file mode 100644 index 0000000..9898170 --- /dev/null +++ b/internal/net_util/net_util.go @@ -0,0 +1,17 @@ +package net_util + +import ( + "net" + "net/netip" + + "github.com/free5gc/ausf/internal/logger" +) + +func RegisterAddr(registerIP string) netip.Addr { + ips, err := net.LookupIP(registerIP) + if err != nil { + logger.InitLog.Errorf("Resolve RegisterIP hostname %s failed: %+v", registerIP, err) + } + ip, _ := netip.ParseAddr(ips[0].String()); + return ip +} diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index 0a5a01b..706112b 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -4,7 +4,7 @@ import ( "context" "fmt" "net/http" - "strconv" + "net/netip" "strings" "sync" "time" @@ -18,6 +18,7 @@ import ( "github.com/free5gc/openapi/Nnrf_NFDiscovery" "github.com/free5gc/openapi/Nnrf_NFManagement" "github.com/free5gc/openapi/models" + "github.com/free5gc/ausf/internal/net_util" ) type nnrfService struct { @@ -200,7 +201,13 @@ func (s *nnrfService) buildNfProfile(ausfContext *ausf_context.AUSFContext) (pro profile.NfInstanceId = ausfContext.NfId profile.NfType = models.NfType_AUSF profile.NfStatus = models.NfStatus_REGISTERED - profile.Ipv4Addresses = append(profile.Ipv4Addresses, ausfContext.RegisterIPv4) + + registerAddr := net_util.RegisterAddr(ausfContext.RegisterIP) + if registerAddr.Is6() { + profile.Ipv6Addresses = append(profile.Ipv6Addresses, ausfContext.RegisterIP) + } else if registerAddr.Is4() { + profile.Ipv4Addresses = append(profile.Ipv4Addresses, ausfContext.RegisterIP) + } services := []models.NfService{} for _, nfService := range ausfContext.NfService { services = append(services, nfService) @@ -235,13 +242,18 @@ func (s *nnrfService) GetUdmUrl(nrfUri string) string { nfDiscoverParam, ) if err != nil { - logger.ConsumerLog.Errorln("[Search UDM UEAU] ", err.Error(), "use defalt udmUrl", udmUrl) + logger.ConsumerLog.Errorln("[Search UDM UEAU] ", err.Error(), "use default udmUrl", udmUrl) } else if len(res.NfInstances) > 0 { udmInstance := res.NfInstances[0] - if len(udmInstance.Ipv4Addresses) > 0 && udmInstance.NfServices != nil { - ueauService := (*udmInstance.NfServices)[0] - ueauEndPoint := (*ueauService.IpEndPoints)[0] - udmUrl = string(ueauService.Scheme) + "://" + ueauEndPoint.Ipv4Address + ":" + strconv.Itoa(int(ueauEndPoint.Port)) + ueauService := (*udmInstance.NfServices)[0] + ueauEndPoint := (*ueauService.IpEndPoints)[0] + port := uint16(ueauEndPoint.Port) + if len(udmInstance.Ipv6Addresses) > 0 && udmInstance.NfServices != nil { + registerIp := net_util.RegisterAddr(ueauEndPoint.Ipv6Address) + udmUrl = string(ueauService.Scheme) + "://" + netip.AddrPortFrom(registerIp, port).String() + } else if len(udmInstance.Ipv4Addresses) > 0 && udmInstance.NfServices != nil { + registerIp := net_util.RegisterAddr(ueauEndPoint.Ipv4Address) + udmUrl = string(ueauService.Scheme) + "://" + netip.AddrPortFrom(registerIp, port).String() } } else { logger.ConsumerLog.Errorln("[Search UDM UEAU] len(NfInstances) = 0") diff --git a/pkg/factory/config.go b/pkg/factory/config.go index e61b852..7b10c97 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -10,6 +10,7 @@ import ( "os" "strconv" "sync" + "net/netip" "github.com/asaskevich/govalidator" @@ -106,16 +107,29 @@ func (c *Configuration) validate() (bool, error) { } type Sbi struct { - Scheme string `yaml:"scheme" valid:"scheme"` - RegisterIPv4 string `yaml:"registerIPv4,omitempty" valid:"host,required"` // IP that is registered at NRF. - BindingIPv4 string `yaml:"bindingIPv4,omitempty" valid:"host,required"` // IP used to run the server in the node. - Port int `yaml:"port,omitempty" valid:"port,required"` + Scheme string `yaml:"scheme" valid:"in(http|https)"` + RegisterIPv4 string `yaml:"registerIPv4,omitempty" valid:"host,optional"` // IP that is registered at NRF. + RegisterIP string `yaml:"registerIP,omitempty" valid:"host,optional"` // IP that is registered at NRF. + BindingIPv4 string `yaml:"bindingIPv4,omitempty" valid:"host,optional"` // IP used to run the server in the node. + BindingIP string `yaml:"bindingIP,omitempty" valid:"host,optional"` // IP used to run the server in the node. + Port int `yaml:"port,omitempty" valid:"port,required,with_register,with_binding"` Tls *Tls `yaml:"tls,omitempty" valid:"optional"` } func (s *Sbi) validate() (bool, error) { - govalidator.TagMap["scheme"] = govalidator.Validator(func(str string) bool { - return str == "https" || str == "http" + govalidator.CustomTypeTagMap.Set("with_register", func(i interface{}, context interface{}) bool { + switch v := context.(type) { + case Sbi: + return (v.RegisterIPv4 != "" && v.RegisterIP == "") || (v.RegisterIP != "" && v.RegisterIPv4 == "") + } + return false + }) + govalidator.CustomTypeTagMap.Set("with_binding", func(i interface{}, context interface{}) bool { + switch v := context.(type) { + case Sbi: + return (v.BindingIPv4 != "" && v.BindingIP == "") || (v.BindingIP != "" && v.BindingIPv4 == "") + } + return false }) if tls := s.Tls; tls != nil { @@ -240,7 +254,10 @@ func (c *Config) GetLogReportCaller() bool { func (c *Config) GetSbiBindingAddr() string { c.RLock() defer c.RUnlock() - return c.GetSbiBindingIP() + ":" + strconv.Itoa(c.GetSbiPort()) + + bindIP, _ := netip.ParseAddr(c.GetSbiBindingIP()); + sbiPort := uint16(c.GetSbiPort()) + return netip.AddrPortFrom(bindIP, sbiPort).String() } func (c *Config) GetSbiBindingIP() string { @@ -250,7 +267,13 @@ func (c *Config) GetSbiBindingIP() string { if c.Configuration == nil || c.Configuration.Sbi == nil { return bindIP } - if c.Configuration.Sbi.BindingIPv4 != "" { + if c.Configuration.Sbi.BindingIP != "" { + if bindIP = os.Getenv(c.Configuration.Sbi.BindingIP); bindIP != "" { + logger.CfgLog.Infof("Parsing ServerIP [%s] from ENV Variable", bindIP) + } else { + bindIP = c.Configuration.Sbi.BindingIP + } + } else if c.Configuration.Sbi.BindingIPv4 != "" { if bindIP = os.Getenv(c.Configuration.Sbi.BindingIPv4); bindIP != "" { logger.CfgLog.Infof("Parsing ServerIPv4 [%s] from ENV Variable", bindIP) } else {