fiorix / go-diameter Goto Github PK
View Code? Open in Web Editor NEWDiameter stack and Base Protocol (RFC 6733) for the Go programming language
License: Other
Diameter stack and Base Protocol (RFC 6733) for the Go programming language
License: Other
I tried to run examples/server/server.go and make a test-request using examples/client/client.go.
the server seems to come up:
dirk:~/gopath/src/github.com/fiorix/go-diameter/examples/server$ go run server.go
2016/10/01 09:28:28 Starting diameter server on :3868
In another shell I open the client, but I am unable to connect
dirk:~/gopath/src/github.com/fiorix/go-diameter/examples/client$ go run client.go
2016/10/01 09:40:50 Use wireshark to see the messages, or try -hello
2016/10/01 09:40:50 no common application
2016/10/01 09:40:52 no common application
Is this expected? I must admit that these are my first steps in go.
The server responds with an error to a simple telnet localhost 3868 as expected. I am using go1.6 on ubuntu 16.4
It would be useful to add a method for updating AVP values. Currently I have been using this helper function:
func ReplaceAVPValue(m *diam.Message, avpName string, avpValue datatype.Type) error {
avp, err := m.FindAVP(avpName)
if err != nil {
return err
}
oldLength := avp.Len()
avp.Data = avpValue
newLength := avp.Len()
m.Header.MessageLength += uint32(newLength) - uint32(oldLength)
return nil
}
But I'm not sure if it works for AVPs that are inside grouped AVP.
Hey,
I think the readme in the front page should inform go-diameter requires "https://github.com/golang/net" library.
Rename the package for a cleaner and more consistent namespace.
When I receive a message I get an error as in subj.
Ethernet layer in wireshark says:
Type: IPv4 (0x0800)
IP layer is decoded as:
Internet Protocol Version 4, Src: 172.20.21.7, Dst: 172.20.17.37
0100 .... = Version: 4
.... 0101 = Header Length: 20 bytes
Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
Total Length: 580
Identification: 0xa4a1 (42145)
Flags: 0x02 (Don't Fragment)
Fragment offset: 0
Time to live: 62
Protocol: TCP (6)
Header checksum: 0x5a51 [validation disabled]
Source: 172.20.21.7
Destination: 172.20.17.37
[Source GeoIP: Unknown]
[Destination GeoIP: Unknown]
Attempting to use state machine in a similar fashion as the client.go
example, results in an error, missing Origin-State-Id
. There's no clear way to update the handshake CER with the AVP in question in the case that it is indeed missing. A snippet from the application is below:
smcli := &sm.Client{
Dict: dict.Default,
Handler: mux,
MaxRetransmits: 3,
RetransmitInterval: time.Second,
EnableWatchdog: true,
WatchdogInterval: 5 * time.Second,
AcctApplicationID: []*diam.AVP{diam.NewAVP(avp.AcctApplicationID, avp.Mbit, 0,
AcctApplicationID),
},
}
// Set message handlers.
mux.HandleFunc("CCA", cl.ccaHandler)
// Print error reports.
go printErrors(mux.ErrorReports())
connect := func() (diam.Conn, error) {
c, err := smcli.Dial(serverAddress)
cl.c = c
return cl.c, err
}
When examining pcap files with Wireshark I see that i quite often get a warning saying AVP is malformed because padding is zero. I have noticed this issue only quite recently so could it be that some recent change is responsible for this?
I am using go-diameter and I need to create a basic server which supports multiple interfaces. How can I accomplish that ?
Thanks
Arpan
This would clean up the clutter of parsing incoming requests.
It seems that there is an issue with OctetString datatype, according to ASN.1 OCTET STRING is a string of octets and should be initialized as a string of octets, not from quoted text, ie. an argument to datatype.OctetString should be passed to network as it is, without further conversion.
I am using this source as a reference - http://luca.ntop.org/Teaching/Appunti/asn1.html , and from what I see the practical application confirms this.
Package sm
always include the Firmware-Revision
AVP in client connections and expect it to exist in server connections during the initial handshake.
This must be optional. See #42 for details.
Seems like only the rule is added but definition is missing which causes the application to fail processing a message that contains such AVP.
I wonder what process has been used to create the dictionary (xml) files, maybe there could be some other missing AVP definitions?
The ErrorReports
method for diam.HandlerFunc
is a plain recursive function with no ending condition. I'm doubting this is intended (I have never used this package).
https://github.com/fiorix/go-diameter/blob/master/diam/server.go#L232
When I use the example client to connect the relay agent, it exits with error:
auth application 4294967295 is not supported
The CEA from relay agent includes the relay application id:
AVP: Auth-Application-Id(258) l=12 f=-M- val=Relay (4294967295)
The relay agent is very standard network entity in diameter network, so does go-diameter supports it?
Rename diam.datatypes to diam.diamtype for a better namespace.
# github.com/fiorix/go-diameter/examples/s6a_proxy/service
src/github.com/fiorix/go-diameter/examples/s6a_proxy/service/s6a_proxy.go:50:16: unknown field 'HostIPAddress' in struct literal of type sm.Settings
I'm trying to connect to a diameter server which accepts only valid origin-host values and only one connection per value. I'm getting this kind of error CEA:
Capabilities-Exchange-Answer (CEA)
{Code:257,Flags:0x20,Version:0x1,Length:192,ApplicationId:0,HopByHopId:0x8a0654a7,EndToEndId:0xe3c8490d}
Result-Code {Code:268,Flags:0x40,Length:12,VendorId:0,Value:Unsigned32{5012}}
Origin-Host {Code:264,Flags:0x40,Length:20,VendorId:0,Value:DiameterIdentity{*hidden*},Padding:0}
Origin-Realm {Code:296,Flags:0x40,Length:28,VendorId:0,Value:DiameterIdentity{*hidden*},Padding:0}
Host-IP-Address {Code:257,Flags:0x40,Length:16,VendorId:0,Value:Address{*hidden*},Padding:2}
Vendor-Id {Code:266,Flags:0x40,Length:12,VendorId:0,Value:Unsigned32{16247}}
Product-Name {Code:269,Flags:0x0,Length:32,VendorId:0,Value:UTF8String{Diameter Control Agent},Padding:2}
Origin-State-Id {Code:278,Flags:0x40,Length:12,VendorId:0,Value:Unsigned32{1484188053}}
Error-Message {Code:281,Flags:0x0,Length:40,VendorId:0,Value:UTF8String{Origin-Host already connected},Padding:3}
At the moment cea.go will try to parse this and since it doesn't contain Auth-Application-ID I get error "ErrMissingApplication". I'd like to get access to the actual error for identifying different error cases. A simple way to do it in cea.go:
// Parse parses and validates the given message.
func (cea *CEA) Parse(m *diam.Message, localRole Role) (err error) {
...
...
if _, err := app.Parse(m.Dictionary(), localRole); err != nil {
if cea.ResultCode != diam.Success {
return nil
}
return err
}
...
with that I get an ErrFailedResultCode with the correct code.
The check for ResultCode could also be just after Unmarshal is called, maybe in sanityCheck. I'm not sure which way would be the best.
I am using client example as a starting point to connect to remote charging system (which is based on https://github.com/RestComm/jdiameter). CER which is sent from the client side includes auth-application-id = 4, remote peer returns auth-application-id = 4 and acct-application-id = 3. Console logs acct application 3 is not supported
and connection is not established.
It looks that go-diameter sm is not behaving correctly since both peers have application in common, but it looks that client expects to support all applications returned in CEA. As specified in RFC6733:
The sender of the Capabilities-Exchange-Answer
(CEA) SHOULD include all of its supported applications as a hint to
the receiver regarding all of its application capabilities.
EDIT: It looks that there are 2 issues here:
This seems like a very extreme measure. According to RFC 6733:
o A request with an unrecognized AVP is received with the 'M' bit
(Mandatory bit) set causes an answer to be sent with the Result-
Code AVP set to DIAMETER_AVP_UNSUPPORTED and the Failed-AVP AVP
containing the offending AVP.
This functionality can't be currently implemented if client is disconnected.
Ideally only AVPs present in the dictionary are parsed but when the message is forwarded again, also the missing AVPS are present. This might need considerable refactoring in the code? Simpler solution would be to at least return an error instead of disconnecting the client.
Currently if AVP doesn't contain any payload it causes go-diameter to panic when parsing the message. The problem happens in unsigned32.go:17, and likewise for other datatypes. Example case where I encountered this is Failed-AVP containing AVP that has no payload.
RFC says:
A Diameter message SHOULD contain one Failed-AVP AVP, containing the
entire AVP that could not be processed successfully. If the failure
reason is omission of a required AVP, an AVP with the missing AVP
code, the missing Vendor-Id, and a zero-filled payload of the minimum
required length for the omitted AVP will be added.
So it seems it is recommended to zero fill the payload but it's not mandatory.
Kind sir, a design question… Using the following logic for a single diameter client which is intended for repeated re-use, there's an issue where the call to c, err := cl.cli.Dial(cl.destinationAddress)
never returns after it gets executed. The aim of doing this is to reconnect in the case of a network interruption, as cli.c
is used for writing CCR messages to a peer. Perhaps this is a case of misuse. Could you please clarify if it should be possible to call cli.Dial
multiple times? The definition of cli
is further below.
func (cl *Client) connect() error {
// Handle locking.
utils.Logln(cl.debug, "connect(diameter://"+cl.DestinationHost()+"):", "dialling")
c, err := cl.cli.Dial(cl.destinationAddress)
if err == nil {
utils.Logln(cl.debug, "connect(diameter://"+cl.DestinationHost()+"):", "acquiring lock")
cl.mut.Lock()
cl.c = c
cl.mut.Unlock()
utils.Logln(cl.debug, "connect(diameter://"+cl.DestinationHost()+"):", "released lock")
}
return err
}
func (cl *Client) Run() {
// Make a persistent connection with back-off.
backoff := time.Second
for {
utils.Logln(cl.debug, "connect(diameter://"+cl.DestinationHost()+"):", "attempting")
err := cl.connect()
if err != nil {
utils.Logln(cl.debug, "connect(diameter-err://"+cl.DestinationHost()+"):", err)
backoff *= 2
if backoff > 20 {
backoff = 20
}
time.Sleep(backoff)
continue
}
utils.Logln(cl.debug, "connect(diameter-h):"+cl.DestinationHost()+"):", "handshake ok")
backoff = 1
// Wait until the server kicks us out or a write fails, requiring a
// reconnect.
select {
case <-cl.c.(diam.CloseNotifier).CloseNotify():
cl.mut.Lock()
cl.c = nil
cl.mut.Unlock()
utils.Logln(cl.debug, "reconnect(diameter://"+cl.DestinationHost()+"):", "initiated")
case <-cl.reconnect:
cl.Close()
utils.Logln(cl.debug, "reconnect(diameter://"+cl.DestinationHost()+"):", "initiated")
}
utils.Logln(cl.debug, "connect(diameter):"+cl.DestinationHost()+"):", "client disconnected - recreating connection")
}
}
type Client struct {
c diam.Conn
cli *sm.Client
destinationAddress string
destinationRealm datatype.DiameterIdentity
destinationHost datatype.DiameterIdentity
originRealm datatype.DiameterIdentity
originHost datatype.DiameterIdentity
productName datatype.UTF8String
reconnect chan struct{}
saveFunc saveOperation
Identifier string
db *sql.DB
mut *sync.RWMutex
debug bool
}
smcli := &sm.Client{
Dict: dict.Default,
Handler: mux,
MaxRetransmits: 3,
RetransmitInterval: time.Second,
EnableWatchdog: true,
WatchdogInterval: 5 * time.Second,
AcctApplicationID: []*diam.AVP{diam.NewAVP(avp.AcctApplicationID, avp.Mbit, 0,
AcctApplicationID),
},
}
// Set message handlers.
mux.HandleFunc("CCA", cl.ccaHandler)
cl.cli = smcli
Thanks for your time & attention.
for a scenario where we have different avp agreements (Dictionary having different response/answer) for
Voice ccr/a , Data ccr/a , Event ccr/a.
1)found that currently code base does not validate the answer
iam planning to enhance the parser to hold commands for different request type and then use them to validate response/answer
any one faced such a scenario ..any other approach used ?
on the RFC 6733 page 61, stated:
"The sender of the Capabilities-Exchange-Answer (CEA) SHOULD include all of its supported applications as a hint to the receiver regarding all of its application capabilities."
but in the implementation on /go-diameter/diam/sm/cer.go
:
if cer.AcctApplicationID != nil {
for _, acct := range cer.AcctApplicationID {
a.AddAVP(acct)
}
}
if cer.AuthApplicationID != nil {
for _, auth := range cer.AuthApplicationID {
a.AddAVP(auth)
}
}
if cer.VendorSpecificApplicationID != nil {
for _, vs := range cer.VendorSpecificApplicationID {
a.AddAVP(vs)
}
}
I just noticed there is a tool that converts wireshark dictionaries to go-diameter dictionaries. I guess there is no tool that does the conversion other way? Of course to prevent this problem one could always just create the wireshark dictionary first, but sometimes to realize this it can be already too late :)
Does go-diameter support DPR/DPA messages?
If not is there a plan to include this?
RFC6733, 7.1.5:
Errors that fall within the permanent failures category are used to
inform the peer that the request failed and should not be attempted
again.
Currently go-diameter sm client attempts to reconnect even if permanent error code (eg. 5010) is received. Steps that take place are:
According to the RFC 6733, at least below features are missing in this implementation?
I think the practical diameter application should need these features.
According to RFC:
"The AVP Code, combined with the Vendor-Id field, identifies the attribute uniquely."
But currently I seem to have some parsing problems if you use a vendor specific AVP with a code that already exists. At least in avp/codes.go this looks a bit odd:
dictAVP, err := dictionary.FindAVP(application, a.Code)
Because the FindAVP doesn't take vendorId as parameter.
# github.com/fiorix/go-diameter/examples/diam_sctp_client
src/github.com/fiorix/go-diameter/examples/diam_sctp_client/main.go:91:41: sctpLAdds.IP undefined (type *sctp.SCTPAddr has no field or method IP)
Found by smallrepo.com:
https://smallrepo.com/builds/20180410-223930-028dc0d3
Hi,
I have hit a panic on normal usage, adding vendor AVPs in a group and trying to send them over network.
Before trying to figure it out by myself, is there any easy/obvious fix for my issue?
Have done a simplified test for my issue here:
https://github.com/cgrates/go-diameter/blob/master/diam/message_test.go#L185
I should mention that adding string before int works just fine and also if int is the last one in group. The only issue is when string follows int.
Thanks in advance!
DanB
func NewMessage
in message.go
accepts a dictionary argument as the final argument:
func NewMessage(cmd uint32, flags uint8, appid, hopbyhop, endtoend uint32, dictionary *dict.Parser) *Message {
however some of the AVP's are shared and are used across multiple dictionaries
For example:
<!-- dict/testdata/base.xml -->
<avp name="Session-Id" code="263" must="M" may="P" must-not="V" may-encrypt="Y">
<data type="UTF8String"/>
</avp>
<!-- dict/testdata/credit_control.xml -->
<command code="272" short="CC" name="Credit-Control">
<request>
<rule avp="Session-Id" required="true" max="1"/>
<rule avp="Origin-Host" required="true" max="1"/>
<!-- More AVP Rules >
I'm not sure what the best approach here is, but maybe we can pass in an array of dictionaries as the final argument to func NewMessage
?
In case of grouped/nested AVPs in the incoming message it is not clear how to properly extract values assigned to those AVPs, for example AVPs defined as follows:
r.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(avp.SubscriptionIDType, avp.Mbit, 0, datatype.Enumerated(0x00)),
diam.NewAVP(avp.SubscriptionIDData, avp.Mbit, 0, datatype.UTF8String(msisdn)),
},
})
or
r.NewAVP(avp.MultipleServicesCreditControl, avp.Mbit, 0, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(avp.RequestedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(avp.CCTime, avp.Mbit, 0, datatype.Unsigned32(120)),
},
}),
},
})
FindAVP seems to work only for the first level of nesting. What would be the recommended way of extracting CCTime for the example above?
I want to change Address
to Addr
but I'm afraid it'll break some people's tests. Although I don't believe a lot of people are using this yet.
Ref: https://github.com/fiorix/go-diameter/blob/master/diam/diamtest/server.go#L19
When trying to decode a message that has AVPs with vendor-ids, that are in the default.go dictionary, ReadMessage errors out with "Failed to decode AVP: Could not find AVP XXX
".
Verified by adding a test case in diam/message_test.go for a message with a Service-Information AVP (873). This is defined in default.go, but missing the vendor-id. This seems to be the case for all AVPs defined in the variable tgpprorfXML
.
Proposed solution is adding vendor-id="10415"
to each of these AVPs in default.go.
(PS Interim solution that worked for me for now was adding a corrected version of the entire tgpprorfXML
section to my custom dictionary).
Will create a pull request for this fix.
I am trying to extend dictionaries with additional AVPs, in particular some from the 3GPP TS 32.299 (http://www.3gpp.org/DynaReport/32299.htm) specification. A forwarning: I am new to Go and relatively new to Diameter.
Based on the credit contol dictionary extension, I have tried to define additional library to be loaded in https://github.com/fiorix/go-diameter/blob/master/diam/dict/default.go and added xml to https://github.com/fiorix/go-diameter/tree/master/diam/dict/testdata. Unfortunately I wasn't able to compile the package due to following error:
gocode/src/github.com/fiorix/go-diameter/diam/dict/default.go:19: syntax error: unexpected name, expecting )
gocode/src/github.com/fiorix/go-diameter/diam/dict/default.go:942: syntax error: unexpected literal 3, expecting name or (
Which are the lines where extension was defined and loaded. I also tried extending autogen.sh in similar fashion with no luck. My first question is therefore: what is the proper way of defining new dictionary?
As a workaround I pushed additional AVP's to existing credit control dictionary and added relevant codes to https://github.com/fiorix/go-diameter/blob/master/diam/avp/codes.go
Which seems to work, client and server can both send and receive new AVP, however respective packages cannot be decoded in wireshark (and wireshark is able to decode these AVP's coming from different application). Extension is defined as follows:
<avp name="Service-Information" code="873" must="V,M" may="P" must-not="-" may-encrypt="N">
<!-- TO DO: put reference information -->-Info
<data type="Grouped">
<rule avp="IMS-Information" required="false" max="1"/>
<!--rule avp="PS-Information" required="false" max="1"/-->
</data>
</avp>
<avp name="IMS-Information" code="876" must="V,M" may="P" must-not="-" may-encrypt="N">
<!-- TO DO: put reference information -->
<data type="Grouped">
<rule avp="Called-Party-Address" required="false" max="1"/>
</data>
</avp>
<avp name="Called-Party-Address" code="832" must="V,M" may="P" must-not="-" may-encrypt="N">
<!-- TO DO: put reference information -->
<data type="UTF8String"/>
</avp>
From the wireshark capture I see that Vendor Specific flag is not set, though it is defined in the dictionary so I guess this could be the reason. Could you please advise what is wrong with these definition, why vendor specific flag is not being set?
I could push some definitions from 3GPP TS 32.299 to your library (just a selected few I need so far) if you don't mind and advise the proper way to add these AVPs
I am just wondering what the best performing decode method is? I am currently using the library to decode from raw bytes that are being collected from a network tap
Generally it works perfectly but occasionally if there is a message storm or some other network issues we can see a huge spike in diameter messages (hundreds of thousands per second), which can cause some issues
I am currently using ReadMessage
on each packet, Just wondering if there is a better method
Thanks
I tried to unmarshal message containing enum AVPs as int32 values but the value was always 0. The reflect_test.go doesn't contain examples of enum AVP types. Am I just doing something wrong or maybe there is some problem with enum types?
go-diameter/diam/network_sctp.go:389:16: l.AcceptSCTP undefined (type sctpListener has no field or method AcceptSCTP)
Currently message AVPs are stored in a slice but wouldn't multi-key dictionary be more appropriate data structure? This would make finding of AVPs faster. Also removal of AVPs will be easier (which seems not to be supported at all).
For some reason I am having trouble pulling this value out using the avp
struct tags, I can clearly see it in my payload and I can see that it is being correctly decoded in util.go
, But I just get an empty time back into my struct.
However it works if I do a FindAVP(avp.EventTimestamp, 0)
I am sure I am just missing something..but I am lost as to what I am messing up. any suggestions?
I can't find a way to send push message from server to client.
Is it supported by go-diameter?
How can I send asynchronous message on event from server to client e.g.:
When using go-diameter examples, or sm handleCER:
Upon receiving a request with hop-by-hop or end-to-end id set to zero, go-diameter will respond with a message containing random hop-by-hop / end-to-end id. The client will then discard the answer.
To the best of my understanding: While RFC 3588 or 6733 encourage the use of unique Hop-by-Hop or End-to-End field values, they do not explicitly forbid zero values. The RFCs do require that Diameter agent respond to a message with hop-by-hop and end-to-end ids equal to those received in the request.
The issue is with lack of distinction method argument zero values, and header zeros copied from request message header fields.
from NewMessage:
if hopbyhop == 0 {
hopbyhop = rand.Uint32()
}
if endtoend == 0 {
endtoend = rand.Uint32()
}
Example of an ugly fix for sm/cer.go successCER:
a := m.Answer(diam.Success)
a.Header.HopByHopID = m.Header.HopByHopID
a.Header.EndToEndID = m.Header.EndToEndID
Hello Fiorix!
I am trying to make GoDiameter to communicate with freeDiameter respectively.
However, received CEA includes three application Ids and one unknown AVP.
Despite DIAMETER_SUCCESS (2001) , freeDiameter fails to parse the response correctly.
freeDiameter Log:
18:02:54 NOTI SND to 'cgrates-poc.opencloud.com':
18:02:54 NOTI 'Capabilities-Exchange-Request'
18:02:54 NOTI Version: 0x01
18:02:54 NOTI Length: 212
18:02:54 NOTI Flags: 0x80 (R---)
18:02:54 NOTI Command Code: 257
18:02:54 NOTI ApplicationId: 0
18:02:54 NOTI Hop-by-Hop Identifier: 0x1BFA6EE1
18:02:54 NOTI End-to-End Identifier: 0x8E10F059
18:02:54 NOTI {internal data}: src:(nil)(0) rwb:(nil) rt:0 cb:(nil),(nil)((nil)) qry:(nil) asso:0 sess:(nil)
18:02:54 NOTI AVP: 'Origin-Host'(264) l=34 f=-M val="freediameter.opencloud.com"
18:02:54 NOTI AVP: 'Origin-Realm'(296) l=21 f=-M val="opencloud.com"
18:02:54 NOTI AVP: 'Origin-State-Id'(278) l=12 f=-M val=1492441313 (0x58f4d8e1)
18:02:54 NOTI AVP: 'Host-IP-Address'(257) l=14 f=-M val=10.224.228.36
18:02:54 NOTI AVP: 'Vendor-Id'(266) l=12 f=-M val=0 (0x0)
18:02:54 NOTI AVP: 'Product-Name'(269) l=20 f=-- val="freeDiameter"
18:02:54 NOTI AVP: 'Firmware-Revision'(267) l=12 f=-- val=10201 (0x27d9)
18:02:54 NOTI AVP: 'Inband-Security-Id'(299) l=12 f=-M val='NO_INBAND_SECURITY' (0 (0x0))
18:02:54 NOTI AVP: 'Acct-Application-Id'(259) l=12 f=-M val=3 (0x3)
18:02:54 NOTI AVP: 'Auth-Application-Id'(258) l=12 f=-M val=4294967295 (0xffffffff)
18:02:54 NOTI AVP: 'Supported-Vendor-Id'(265) l=12 f=-M val=5535 (0x159f)
18:02:54 NOTI AVP: 'Supported-Vendor-Id'(265) l=12 f=-M val=10415 (0x28af)
18:02:54 DBG 'STATE_WAITCNXACK' -> 'STATE_WAITCEA' 'cgrates-poc.opencloud.com'
18:02:54 NOTI Unsupported mandatory AVP found
18:02:54 ERROR Unsupported AVP: 0(not searched in dictionary) l=12 f=-M val=(not set)
18:02:54 ERROR ERROR: in '((parsedict_do_avp(dict, ((struct avp *)(avpch->o)), mandatory, error_info)))' : Operation not supported
18:02:54 ERROR ERROR: in '((parsedict_do_avp(dict, ((struct avp *)(avpch->o)), mandatory, error_info)))' : Operation not supported
18:02:54 NOTI RCV from 'cgrates-poc.opencloud.com':
18:02:54 NOTI 'Capabilities-Exchange-Answer'
18:02:54 NOTI Version: 0x01
18:02:54 NOTI Length: 228
18:02:54 NOTI Flags: 0x00 (----)
18:02:54 NOTI Command Code: 257
18:02:54 NOTI ApplicationId: 0
18:02:54 NOTI Hop-by-Hop Identifier: 0x1BFA6EE1
18:02:54 NOTI End-to-End Identifier: 0x8E10F059
18:02:54 NOTI {internal data}: src:cgrates-poc.opencloud.com(25) rwb:0x7f8ffc0019f0 rt:0 cb:(nil),(nil)((nil)) qry:0x7f90040012f0 asso:0 sess:(nil)
18:02:54 NOTI AVP: 'Result-Code'(268) l=12 f=-M val='DIAMETER_SUCCESS' (2001 (0x7d1))
18:02:54 NOTI AVP: 'Origin-Host'(264) l=19 f=-M val="cgrates-poc"
18:02:54 NOTI AVP: 'Origin-Realm'(296) l=21 f=-M val="opencloud.com"
18:02:54 NOTI AVP: 'Host-IP-Address'(257) l=14 f=-M val=10.224.228.186
18:02:54 NOTI AVP: 'Vendor-Id'(266) l=12 f=-M val=0 (0x0)
18:02:54 NOTI AVP: 'Product-Name'(269) l=19 f=-- val="Golant-data"
18:02:54 NOTI AVP: 'Origin-State-Id'(278) l=12 f=-M val=1492441313 (0x58f4d8e1)
18:02:54 NOTI AVP: 'Acct-Application-Id'(259) l=12 f=-M val=3 (0x3)
18:02:54 NOTI AVP: 'Auth-Application-Id'(258) l=12 f=-M val=4 (0x4)
18:02:54 NOTI AVP: 'Auth-Application-Id'(258) l=12 f=-M val=1 (0x1)
18:02:54 NOTI AVP: 'Supported-Vendor-Id'(265) l=12 f=-M val=10415 (0x28af)
18:02:54 NOTI AVP: 'Vendor-Specific-Application-Id'(260) l=32 f=-M val=(grouped)
18:02:54 NOTI AVP: 'Vendor-Id'(266) l=12 f=-M val=10415 (0x28af)
18:02:54 NOTI AVP: 0(not searched in dictionary) l=12 f=-M val=(not set)
18:02:54 NOTI AVP: 267(not searched in dictionary) l=12 f=-- val=(not set)
18:02:54 NOTI Unsupported mandatory AVP found
Trace:
Diameter Protocol
Version: 0x01
Length: 196
Flags: 0x00
Command Code: 257 Capabilities-Exchange
ApplicationId: Diameter Common Messages (0)
Hop-by-Hop Identifier: 0x5ff41e87
End-to-End Identifier: 0xc68a0593
[Request In: 124]
[Response Time: 0.000189000 seconds]
AVP: Result-Code(268) l=12 f=-M- val=DIAMETER_SUCCESS (2001)
AVP: Origin-Host(264) l=19 f=-M- val=cgrates-poc
AVP: Origin-Realm(296) l=21 f=-M- val=opencloud.com
AVP: Host-IP-Address(257) l=14 f=-M- val=10.224.228.186
AVP: Vendor-Id(266) l=12 f=-M- val=10415
AVP: Product-Name(269) l=19 f=--- val=Golant-data
AVP: Origin-State-Id(278) l=12 f=-M- val=1492106344
AVP: Acct-Application-Id(259) l=12 f=-M- val=Diameter Base Accounting (3)
AVP: Auth-Application-Id(258) l=12 f=-M- val=Diameter Credit Control Application (4)
AVP: Auth-Application-Id(258) l=12 f=-M- val=NASREQ Application (1)
**AVP: Unknown(0) l=12 f=-M- val=00000004**
AVP: Firmware-Revision(267) l=12 f=--- val=918
From the documentation, I understand that actually four dictionaries (applications) are pre-loaded in.
Embedded dictionaries:
- Base Protocol RFC 6733
- Credit Control RFC 4006
- Network Access Server RFC 7155
- 3GPP specific AVPs from TS 32.299 version 12.7.0 <=== What is that exactly and what is used for ?
I am a newbie in diameter world, but I feel, it could be related to to RFC3588 and "Vendor-Specific-Application-Id" grouped AVP.
Could you kindly point me towards the reason why that particular unknown AVP appears in the answer and which dictionary could possibly make freeDiameter understand that?
Is there a way to disable those specific AVPs from being added to CEA, since I only need DCCA?
Just tried to comment out the following in the autogen.sh file, and running it, then building the project.
// Default is a Parser object with pre-loaded
// Base Protocol and Credit Control dictionaries.
var Default *Parser
func init() {
Default, _ = NewParser()
// Default.Load(bytes.NewReader([]byte(baseXML)))
Default.Load(bytes.NewReader([]byte(creditcontrolXML)))
// Default.Load(bytes.NewReader([]byte(networkaccessserverXML)))
// Default.Load(bytes.NewReader([]byte(tgpprorfXML)))
}
The AVP is removed, but freeDiameter rejects the session without base dictionary, so, I think it is mandatory.
This is more like a question, still not sure where is the exact issue.
Please assist,
Thanks in advance,
I am just wondering if there is any helpers do deal with multiple diameter payloads within a single TCP packet?
Currently i have some that contain up to 4 distinct diameter messages per payload
sorry if i have missed something obvious
Hi @fiorix, firstly may thanks for this library. I just started using it today and I'm having some trouble with the Grouped
datatype.
I added the following AVP definitions to the dictionary according to http://tools.ietf.org/html/rfc4006#section-8.46
<diameter>
<application id="0">
<avp name="Subscription-Id" code="443" must="M" may="P" must-not="V" may-encrypt="-">
<data type="Grouped"/>
</avp>
<avp name="Subscription-Id-Type" code="450" must="M" may="P" must-not="V" may-encrypt="Y">
<data type="Enumerated">
<item code="0" name="END_USER_E164"/>
<item code="1" name="END_USER_IMSI"/>
<item code="2" name="END_USER_SIP_URI"/>
<item code="3" name="END_USER_NAI"/>
</data>
</avp>
<avp name="Subscription-Id-Data" code="444" must="M" may="P" must-not="V" may-encrypt="Y">
<data type="UTF8String"/>
</avp>
</application>
</diameter>
In my client I've done this:
const (
SubscriptionIdType = datatypes.Enumerated(0x00)
SubscriptionIdData = datatypes.UTF8String("85560234567")
)
func NewClient(c diam.Conn) {
m := diam.NewRequest(272, 0, nil)
m.NewAVP("Subscription-Id", 0x40, 0x0, datatypes.Grouped([SubscriptionIdType, SubscriptionIdData]))
Just having a problem with the last line. How to make a NewAVP
which is of type Grouped
and contains the other two types?
I don't know is RFC 6733 give some requirement about this. But in the real case, I'm facing that acct-application-id and auth-application-id share same id.
Hi,
Lack of SCTP support clearly discourages people to use GO based diameter backends at the moment.
I know it's not nice to have c bindings but is there a chance that you would consider it, leveraging https://github.com/sctplab/usrsctp library?
When trying to send Credit Control message to server (go-diameter/examples/server/server.go) server generates error message:
Could not find preloaded Command with code 272
While error is self-explanatory it is not clear how it can be remedied. If server example is correct could you please provide an update to wiki how to properly extend server and client examples to handle CreditControl command?
See also #1
Create a dictionary for credit control http://tools.ietf.org/html/rfc4006 and put it in dict/testdata/cc.xml
then make a copy of it in ccdict.go
. Some of the AVP's have already been described here dwilkie@e915deb
Attempting to install the package currently fails with an import cycle error.
micrypt@box /usr/local/bin [master] $ echo $GOPATH
/Users/micrypt/silo/gocode
micrypt@box /usr/local/bin [master] $ echo $GOROOT
/Users/micrypt/silo/go
micrypt@box /usr/local/bin [master] $ go get github.com/fiorix/go-diameter/diam
import cycle not allowed
package github.com/fiorix/go-diameter/diam
imports bufio
imports bytes
imports errors
imports runtime
imports runtime/internal/atomic
imports runtime
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.