diff --git a/sessions/apis.go b/sessions/apis.go index 76f58de33..2645cfc59 100644 --- a/sessions/apis.go +++ b/sessions/apis.go @@ -85,7 +85,12 @@ func (sS *SessionS) BiRPCv1AuthorizeEvent(ctx *context.Context, utils.MetaResources); err != nil { return } - if !attrS && !acntS && !resourceS && !routeS { + var ipS bool + if ipS, err = engine.GetBoolOpts(ctx, args.Tenant, dP, nil, sS.fltrS, sS.cfg.SessionSCfg().Opts.IPsAuthorize, + utils.MetaIPs); err != nil { + return + } + if !attrS && !acntS && !resourceS && !ipS && !routeS { return // Nothing to do } if args.APIOpts == nil { @@ -145,6 +150,23 @@ func (sS *SessionS) BiRPCv1AuthorizeEvent(ctx *context.Context, } authReply.ResourceAllocation = &allocMsg } + if ipS { + if len(sS.cfg.SessionSCfg().IPsConns) == 0 { + return utils.NewErrNotConnected(utils.IPs) + } + originID, _ := args.FieldAsString(utils.OriginID) + if originID == "" { + originID = utils.UUIDSha1Prefix() + } + args.APIOpts[utils.OptsIPsUsageID] = originID + args.APIOpts[utils.OptsIPsUnits] = 1 + var allocMsg string + if err = sS.connMgr.Call(ctx, sS.cfg.SessionSCfg().IPsConns, utils.IPsV1AuthorizeIPs, + args, &allocMsg); err != nil { + return utils.NewErrIPs(err) + } + authReply.IPAllocation = &allocMsg + } if routeS { routesReply, err := sS.getRoutes(ctx, args.Clone()) if err != nil { @@ -287,7 +309,12 @@ func (sS *SessionS) BiRPCv1InitiateSession(ctx *context.Context, utils.MetaResources); err != nil { return } - if !acntS && !resourceS { + var ipS bool + if ipS, err = engine.GetBoolOpts(ctx, args.Tenant, dP, nil, sS.fltrS, sS.cfg.SessionSCfg().Opts.IPsAllocate, + utils.MetaIPs); err != nil { + return + } + if !acntS && !resourceS && !ipS { return // Nothing to do } @@ -355,6 +382,34 @@ func (sS *SessionS) BiRPCv1InitiateSession(ctx *context.Context, } }() + } + if ipS { + if len(sS.cfg.SessionSCfg().IPsConns) == 0 { + return utils.NewErrNotConnected(utils.IPs) + } + if originID == utils.EmptyString { + return utils.NewErrMandatoryIeMissing(utils.OriginID) + } + args.APIOpts[utils.OptsIPsUsageID] = originID + args.APIOpts[utils.OptsIPsUnits] = 1 + var allocMessage string + if err = sS.connMgr.Call(ctx, sS.cfg.SessionSCfg().IPsConns, + utils.IPsV1AllocateIPs, args, &allocMessage); err != nil { + return utils.NewErrIPs(err) + } + rply.IPAllocation = &allocMessage + defer func() { // we need to release the IPs back in case of errors + if err != nil { + var reply string + if err = sS.connMgr.Call(ctx, sS.cfg.SessionSCfg().IPsConns, utils.IPsV1ReleaseIPs, + args, &reply); err != nil { + utils.Logger.Warning( + fmt.Sprintf("<%s> error: %s releasing IPs for event %+v.", + utils.SessionS, err.Error(), args)) + } + } + }() + } if acntS { diff --git a/sessions/libsessions.go b/sessions/libsessions.go index 922577047..cb981847d 100644 --- a/sessions/libsessions.go +++ b/sessions/libsessions.go @@ -438,6 +438,7 @@ func (v1Rply *V1ProcessMessageReply) AsNavigableMap() map[string]*utils.DataNode type V1AuthorizeReply struct { Attributes *attributes.AttrSProcessEventReply `json:",omitempty"` ResourceAllocation *string `json:",omitempty"` + IPAllocation *string `json:",omitempty"` MaxUsage *utils.Decimal `json:",omitempty"` RouteProfiles routes.SortedRoutesList `json:",omitempty"` ThresholdIDs *[]string `json:",omitempty"` @@ -514,6 +515,7 @@ type V1AuthorizeReplyWithDigest struct { type V1InitSessionReply struct { Attributes *attributes.AttrSProcessEventReply `json:",omitempty"` ResourceAllocation *string `json:",omitempty"` + IPAllocation *string `json:",omitempty"` MaxUsage *time.Duration `json:",omitempty"` ThresholdIDs *[]string `json:",omitempty"` StatQueueIDs *[]string `json:",omitempty"` diff --git a/sessions/sessions.go b/sessions/sessions.go index 94984b2ba..eaa4b6da0 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -368,6 +368,21 @@ func (sS *SessionS) forceSTerminate(ctx *context.Context, s *Session, extraUsage utils.SessionS, err.Error(), s.ID)) } } + // release the ips for the session + if len(sS.cfg.SessionSCfg().IPsConns) != 0 { + var reply string + args := s.OriginCGREvent.Clone() + args.ID = utils.UUIDSha1Prefix() + args.APIOpts[utils.OptsIPsUsageID] = s.ID + args.APIOpts[utils.OptsIPsUnits] = 1 + if err := sS.connMgr.Call(ctx, sS.cfg.SessionSCfg().IPsConns, + utils.IPsV1ReleaseIPs, + args, &reply); err != nil { + utils.Logger.Warning( + fmt.Sprintf("<%s> error: %s could not release IP %q", + utils.SessionS, err.Error(), s.ID)) + } + } sS.replicateSessions(ctx, s.ID, false, sS.cfg.SessionSCfg().ReplicationConns) if clntConn := sS.biJClnt(s.ClientConnID); clntConn != nil { go func() { diff --git a/utils/errors.go b/utils/errors.go index 9ebb3694b..aadb80c4e 100644 --- a/utils/errors.go +++ b/utils/errors.go @@ -172,10 +172,15 @@ func NewErrServerError(err error) error { func NewErrNotConnected(serv string) error { return fmt.Errorf("NOT_CONNECTED: %s", serv) } + func NewErrResourceS(err error) error { return fmt.Errorf("RESOURCES_ERROR:%s", err) } +func NewErrIPs(err error) error { + return fmt.Errorf("IPS_ERROR:%s", err) +} + func NewErrRouteS(err error) error { return fmt.Errorf("ROUTES_ERROR:%s", err) }