From 7997e42be55a1939526d153bc3dcec111e355133 Mon Sep 17 00:00:00 2001 From: TeoV Date: Fri, 7 Dec 2018 07:22:51 -0800 Subject: [PATCH] Add support for *remote_host in AgentRequest --- agents/agentreq.go | 21 +++++++++------------ agents/agentreq_test.go | 25 +------------------------ agents/diamagent.go | 2 +- agents/libdiam.go | 12 +++++++++--- agents/libdiam_test.go | 2 +- agents/libhttpagent.go | 31 ++++++++++++++++++++++++++++++- agents/librad.go | 6 ++++++ cdrc/csv.go | 6 ++++++ cdrc/fwv.go | 6 ++++++ cdrc/xml.go | 6 ++++++ config/dataprovider.go | 3 +++ config/navigablemap.go | 7 +++++++ engine/action.go | 6 ++++++ engine/calldesc.go | 6 ++++++ glide.lock | 2 +- loaders/libloader.go | 6 ++++++ utils/consts.go | 2 ++ utils/dateseries.go | 10 ++++++++++ 18 files changed, 116 insertions(+), 43 deletions(-) diff --git a/agents/agentreq.go b/agents/agentreq.go index 2d2ab4a39..205cfb978 100644 --- a/agents/agentreq.go +++ b/agents/agentreq.go @@ -78,6 +78,11 @@ func (ar *AgentRequest) String() string { return utils.ToJSON(ar) } +// RemoteHost implements engine.DataProvider +func (aReq *AgentRequest) RemoteHost() net.Addr { + return aReq.Request.RemoteHost() +} + // FieldAsInterface implements engine.DataProvider func (ar *AgentRequest) FieldAsInterface(fldPath []string) (val interface{}, err error) { switch fldPath[0] { @@ -171,6 +176,9 @@ func (aReq *AgentRequest) ParseField( case utils.META_CONSTANT: out, err = cfgFld.Value.ParseValue(utils.EmptyString) isString = true + case utils.MetaRemoteHost: + out = aReq.RemoteHost().String() + isString = true case utils.MetaVariable, utils.META_COMPOSED: out, err = cfgFld.Value.ParseDataProvider(aReq, utils.NestingSep) isString = true @@ -243,19 +251,8 @@ func (aReq *AgentRequest) ParseField( iFaceVals[i] = utils.StringToInterface(strVal) } out, err = utils.Sum(iFaceVals...) - case utils.MetaRemoteHost: - netInterfaceAddresses, err := net.InterfaceAddrs() - if err != nil { - return "", err - } - for _, netInterfaceAddress := range netInterfaceAddresses { - networkIp, ok := netInterfaceAddress.(*net.IPNet) - if ok && !networkIp.IP.IsLoopback() && networkIp.IP.To4() != nil { - out = networkIp.IP.String() - break - } - } } + if err != nil && !strings.HasPrefix(err.Error(), "Could not find") { return diff --git a/agents/agentreq_test.go b/agents/agentreq_test.go index bc49219be..8c0ee71fb 100644 --- a/agents/agentreq_test.go +++ b/agents/agentreq_test.go @@ -176,7 +176,7 @@ func TestAgReqParseFieldDiameter(t *testing.T) { diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(20000)), }}) //create diameterDataProvider - dP := newDADataProvider(m) + dP := newDADataProvider(nil, m) data, _ := engine.NewMapStorage() dm := engine.NewDataManager(data) cfg, _ := config.NewDefaultCGRConfig() @@ -356,26 +356,3 @@ func TestAgReqParseFieldHttpXml(t *testing.T) { } } - -func TestAgReqParseFieldRemoteHost(t *testing.T) { - data, _ := engine.NewMapStorage() - dm := engine.NewDataManager(data) - cfg, _ := config.NewDefaultCGRConfig() - filterS := engine.NewFilterS(cfg, nil, dm) - agReq := newAgentRequest(nil, nil, nil, nil, "cgrates.org", "", filterS) - - tplFlds := []*config.FCTemplate{ - &config.FCTemplate{Tag: "OriginHost", - FieldId: utils.OriginHost, Type: utils.MetaRemoteHost}, - } - eMp := config.NewNavigableMap(nil) - eMp.Set([]string{utils.OriginHost}, []*config.NMItem{ - &config.NMItem{Data: "192.168.56.203", Path: []string{utils.OriginHost}, - Config: tplFlds[0]}}, false, true) - if mpOut, err := agReq.AsNavigableMap(tplFlds); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(eMp, mpOut) { - t.Errorf("expecting: %+v, received: %+v", eMp, mpOut) - } - -} diff --git a/agents/diamagent.go b/agents/diamagent.go index 43a38c294..b48a52399 100644 --- a/agents/diamagent.go +++ b/agents/diamagent.go @@ -157,7 +157,7 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) { var lclProcessed bool lclProcessed, err = da.processRequest(reqProcessor, newAgentRequest( - newDADataProvider(m), reqVars, rply, + newDADataProvider(c, m), reqVars, rply, reqProcessor.Tenant, da.cgrCfg.GeneralCfg().DefaultTenant, utils.FirstNonEmpty(reqProcessor.Timezone, da.cgrCfg.GeneralCfg().DefaultTimezone), diff --git a/agents/libdiam.go b/agents/libdiam.go index 22fe16ddf..50aad6e49 100644 --- a/agents/libdiam.go +++ b/agents/libdiam.go @@ -266,14 +266,15 @@ func writeOnConn(c diam.Conn, m *diam.Message) { } // newDADataProvider constructs a DataProvider for a diameter message -func newDADataProvider(m *diam.Message) config.DataProvider { - return &diameterDP{m: m, cache: config.NewNavigableMap(nil)} +func newDADataProvider(c diam.Conn, m *diam.Message) config.DataProvider { + return &diameterDP{c: c, m: m, cache: config.NewNavigableMap(nil)} } // diameterDP implements engine.DataProvider, serving as diam.Message data decoder // decoded data is only searched once and cached type diameterDP struct { + c diam.Conn m *diam.Message cache *config.NavigableMap } @@ -300,6 +301,11 @@ func (dP *diameterDP) FieldAsString(fldPath []string) (data string, err error) { return utils.IfaceAsString(valIface) } +// RemoteHost is part of engine.DataProvider interface +func (dP *diameterDP) RemoteHost() net.Addr { + return dP.c.RemoteAddr() +} + // FieldAsInterface is part of engine.DataProvider interface func (dP *diameterDP) FieldAsInterface(fldPath []string) (data interface{}, err error) { if data, err = dP.cache.FieldAsInterface(fldPath); err != nil { @@ -446,7 +452,7 @@ func diamErr(m *diam.Message, resCode uint32, tpl []*config.FCTemplate, tnt, tmz string, filterS *engine.FilterS) (a *diam.Message, err error) { aReq := newAgentRequest( - newDADataProvider(m), reqVars, + newDADataProvider(nil, m), reqVars, config.NewNavigableMap(nil), nil, tnt, tmz, filterS) var rplyData *config.NavigableMap diff --git a/agents/libdiam_test.go b/agents/libdiam_test.go index a71dbe400..954d13cdb 100644 --- a/agents/libdiam_test.go +++ b/agents/libdiam_test.go @@ -64,7 +64,7 @@ func TestDPFieldAsInterface(t *testing.T) { diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(20000)), }}) - dP := newDADataProvider(m) + dP := newDADataProvider(nil, m) eOut := interface{}("simuhuawei;1449573472;00002") if out, err := dP.FieldAsInterface([]string{"Session-Id"}); err != nil { t.Error(err) diff --git a/agents/libhttpagent.go b/agents/libhttpagent.go index e9cbdbedb..1a5bd549c 100644 --- a/agents/libhttpagent.go +++ b/agents/libhttpagent.go @@ -22,6 +22,7 @@ import ( "encoding/xml" "fmt" "io/ioutil" + "net" "net/http" "net/http/httputil" "strconv" @@ -100,6 +101,11 @@ func (hU *httpUrlDP) AsNavigableMap([]*config.FCTemplate) ( return nil, utils.ErrNotImplemented } +// RemoteHost is part of engine.DataProvider interface +func (hU *httpUrlDP) RemoteHost() net.Addr { + return newHttpRemoteAddr(hU.req.RemoteAddr) +} + func newHTTPXmlDP(req *http.Request) (dP config.DataProvider, err error) { byteData, err := ioutil.ReadAll(req.Body) if err != nil { @@ -110,7 +116,7 @@ func newHTTPXmlDP(req *http.Request) (dP config.DataProvider, err error) { if err != nil { return nil, err } - dP = &httpXmlDP{xmlDoc: doc, cache: config.NewNavigableMap(nil)} + dP = &httpXmlDP{xmlDoc: doc, cache: config.NewNavigableMap(nil), addr: req.RemoteAddr} return } @@ -119,6 +125,7 @@ func newHTTPXmlDP(req *http.Request) (dP config.DataProvider, err error) { type httpXmlDP struct { cache *config.NavigableMap xmlDoc *xmlquery.Node + addr string } // String is part of engine.DataProvider interface @@ -189,6 +196,11 @@ func (hU *httpXmlDP) AsNavigableMap([]*config.FCTemplate) ( return nil, utils.ErrNotImplemented } +// RemoteHost is part of engine.DataProvider interface +func (hU *httpXmlDP) RemoteHost() net.Addr { + return newHttpRemoteAddr(hU.addr) +} + // httpAgentReplyEncoder will encode []*engine.NMElement // and write content to http writer type httpAgentReplyEncoder interface { @@ -233,3 +245,20 @@ func (xE *haXMLEncoder) Encode(nM *config.NavigableMap) (err error) { _, err = xE.w.Write(xmlOut) return } + +func newHttpRemoteAddr(ip string) *httpRemoteAddr { + return &httpRemoteAddr{ip: ip} + +} + +type httpRemoteAddr struct { + ip string +} + +func (http *httpRemoteAddr) Network() string { + return utils.TCP +} + +func (http *httpRemoteAddr) String() string { + return http.ip +} diff --git a/agents/librad.go b/agents/librad.go index 96c41144b..919d2753b 100644 --- a/agents/librad.go +++ b/agents/librad.go @@ -20,6 +20,7 @@ package agents import ( "fmt" + "net" "strings" "github.com/cgrates/cgrates/config" @@ -189,3 +190,8 @@ func (pk *radiusDP) AsNavigableMap([]*config.FCTemplate) ( nm *config.NavigableMap, err error) { return nil, utils.ErrNotImplemented } + +// RemoteHost is part of engine.DataProvider interface +func (pk *radiusDP) RemoteHost() net.Addr { + return pk.req.RemoteAddr() +} diff --git a/cdrc/csv.go b/cdrc/csv.go index 466af8e06..f6e314e99 100644 --- a/cdrc/csv.go +++ b/cdrc/csv.go @@ -22,6 +22,7 @@ import ( "encoding/csv" "encoding/json" "fmt" + "net" "strconv" "strings" "time" @@ -272,3 +273,8 @@ func (cP *csvProvider) AsNavigableMap([]*config.FCTemplate) ( nm *config.NavigableMap, err error) { return nil, utils.ErrNotImplemented } + +// RemoteHost is part of engine.DataProvider interface +func (cP *csvProvider) RemoteHost() net.Addr { + return new(utils.LocalAddr) +} diff --git a/cdrc/fwv.go b/cdrc/fwv.go index ddc21276d..0036fcde3 100644 --- a/cdrc/fwv.go +++ b/cdrc/fwv.go @@ -23,6 +23,7 @@ import ( "encoding/json" "fmt" "io" + "net" "net/http" "os" "strconv" @@ -321,3 +322,8 @@ func (fP *fwvProvider) AsNavigableMap([]*config.FCTemplate) ( nm *config.NavigableMap, err error) { return nil, utils.ErrNotImplemented } + +// RemoteHost is part of engine.DataProvider interface +func (fP *fwvProvider) RemoteHost() net.Addr { + return new(utils.LocalAddr) +} diff --git a/cdrc/xml.go b/cdrc/xml.go index a05cc6586..3c67129ba 100644 --- a/cdrc/xml.go +++ b/cdrc/xml.go @@ -23,6 +23,7 @@ import ( "errors" "fmt" "io" + "net" "strconv" "strings" "time" @@ -275,3 +276,8 @@ func (xP *xmlProvider) AsNavigableMap([]*config.FCTemplate) ( nm *config.NavigableMap, err error) { return nil, utils.ErrNotImplemented } + +// RemoteHost is part of engine.DataProvider interface +func (xP *xmlProvider) RemoteHost() net.Addr { + return new(utils.LocalAddr) +} diff --git a/config/dataprovider.go b/config/dataprovider.go index dab21a865..01a403eff 100644 --- a/config/dataprovider.go +++ b/config/dataprovider.go @@ -18,10 +18,13 @@ along with this program. If not, see package config +import "net" + // DataProvider is a data source from multiple formats type DataProvider interface { String() string // printable version of data FieldAsInterface(fldPath []string) (interface{}, error) FieldAsString(fldPath []string) (string, error) AsNavigableMap([]*FCTemplate) (*NavigableMap, error) + RemoteHost() net.Addr } diff --git a/config/navigablemap.go b/config/navigablemap.go index 41ad72f96..e00b0d200 100644 --- a/config/navigablemap.go +++ b/config/navigablemap.go @@ -22,6 +22,7 @@ import ( "encoding/xml" "errors" "fmt" + "net" "strconv" "strings" "time" @@ -162,10 +163,16 @@ func (nM *NavigableMap) FieldAsString(fldPath []string) (fldVal string, err erro return } +// String is part of engine.DataProvider interface func (nM *NavigableMap) String() string { return utils.ToJSON(nM.data) } +// RemoteHost is part of engine.DataProvider interface +func (nM *NavigableMap) RemoteHost() net.Addr { + return new(utils.LocalAddr) +} + // indexMapElements will recursively go through map and index the element paths into elmns func indexMapElements(mp map[string]interface{}, path []string, vals *[]interface{}) { for k, v := range mp { diff --git a/engine/action.go b/engine/action.go index 0d7f68851..0bf6a8008 100644 --- a/engine/action.go +++ b/engine/action.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" "html/template" + "net" "net/smtp" "path" "reflect" @@ -902,3 +903,8 @@ func (cdrP *cdrLogProvider) AsNavigableMap([]*config.FCTemplate) ( nm *config.NavigableMap, err error) { return nil, utils.ErrNotImplemented } + +// RemoteHost is part of engine.DataProvider interface +func (cdrP *cdrLogProvider) RemoteHost() net.Addr { + return new(utils.LocalAddr) +} diff --git a/engine/calldesc.go b/engine/calldesc.go index 97acdae8b..3ad9c35e4 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -21,6 +21,7 @@ package engine import ( "errors" "fmt" + "net" "reflect" "time" @@ -1091,3 +1092,8 @@ func (cd *CallDescriptor) String() string { func (cd *CallDescriptor) AsNavigableMap(tpl []*config.FCTemplate) (nM *config.NavigableMap, err error) { return nil, utils.ErrNotImplemented } + +// RemoteHost is part of utils.DataProvider +func (cd *CallDescriptor) RemoteHost() net.Addr { + return new(utils.LocalAddr) +} diff --git a/glide.lock b/glide.lock index c476211d7..1e051cacb 100644 --- a/glide.lock +++ b/glide.lock @@ -18,7 +18,7 @@ imports: - name: github.com/cgrates/osipsdagram version: 3d6beed663452471dec3ca194137a30d379d9e8f - name: github.com/cgrates/radigo - version: 69d4269e21990c0f120b8e60d5b75d533db7f3dd + version: e5c8f3272cccf795f47b82e25a8f3408312c14e0 - name: github.com/cgrates/rpcclient version: 7316bff37a2b8692fbadd57f9c9cda070cc33081 - name: github.com/fiorix/go-diameter diff --git a/loaders/libloader.go b/loaders/libloader.go index af02f8277..547dc18fc 100644 --- a/loaders/libloader.go +++ b/loaders/libloader.go @@ -20,6 +20,7 @@ package loaders import ( "fmt" + "net" "strconv" "github.com/cgrates/cgrates/config" @@ -135,3 +136,8 @@ func (cP *csvProvider) AsNavigableMap([]*config.FCTemplate) ( nm *config.NavigableMap, err error) { return nil, utils.ErrNotImplemented } + +// RemoteHost is part of engine.DataProvider interface +func (cP *csvProvider) RemoteHost() net.Addr { + return new(utils.LocalAddr) +} diff --git a/utils/consts.go b/utils/consts.go index 6f2b413cd..a0ae7065a 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -536,6 +536,8 @@ const ( IdxEnd = "]" MetaLog = "*log" MetaRemoteHost = "*remote_host" + Local = "local" + TCP = "tcp" ) // Migrator Action diff --git a/utils/dateseries.go b/utils/dateseries.go index 10f229fb8..7d119a66a 100644 --- a/utils/dateseries.go +++ b/utils/dateseries.go @@ -339,3 +339,13 @@ func DaysInYear(year int) float64 { last := first.AddDate(1, 0, 0) return float64(last.Sub(first).Hours() / 24) } + +type LocalAddr struct{} + +func (lc *LocalAddr) Network() string { + return Local +} + +func (lc *LocalAddr) String() string { + return Local +}