forked from fiorix/go-diameter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cer.go
71 lines (65 loc) · 2.64 KB
/
cer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Copyright 2013-2015 go-diameter authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package smparser
import (
"github.com/mohammad-safakhou/go-diameter/v4/diam"
"github.com/mohammad-safakhou/go-diameter/v4/diam/datatype"
)
// CER is a Capabilities-Exchange-Request message.
// See RFC 6733 section 5.3.1 for details.
type CER struct {
OriginHost datatype.DiameterIdentity `avp:"Origin-Host"`
OriginRealm datatype.DiameterIdentity `avp:"Origin-Realm"`
OriginStateID *diam.AVP `avp:"Origin-State-Id"`
InbandSecurityID *diam.AVP `avp:"Inband-Security-Id"`
AcctApplicationID []*diam.AVP `avp:"Acct-Application-Id"`
AuthApplicationID []*diam.AVP `avp:"Auth-Application-Id"`
VendorSpecificApplicationID []*diam.AVP `avp:"Vendor-Specific-Application-Id"`
appID []uint32 // List of supported application IDs.
}
// Parse parses and validates the given message, and returns nil when
// all AVPs are ok, and all accounting or authentication applications
// in the CER match the applications in our dictionary. If one or more
// mandatory AVPs are missing, it returns a nil failedAVP and a proper
// error. If all mandatory AVPs are present but no common application
// is found, then it returns the failedAVP (with the application that
// we don't support in our dictionary) and an error. Another cause
// for error is the presence of Inband Security, we don't support that.
func (cer *CER) Parse(m *diam.Message, localRole Role) (failedAVP *diam.AVP, err error) {
if err = m.Unmarshal(cer); err != nil {
return nil, err
}
if err = cer.sanityCheck(); err != nil {
return nil, err
}
if cer.InbandSecurityID != nil {
if v := cer.InbandSecurityID.Data.(datatype.Unsigned32); v != 0 {
return nil, ErrNoCommonSecurity
}
}
app := &Application{
AcctApplicationID: cer.AcctApplicationID,
AuthApplicationID: cer.AuthApplicationID,
VendorSpecificApplicationID: cer.VendorSpecificApplicationID,
}
if failedAVP, err = app.Parse(m.Dictionary(), localRole); err != nil {
return failedAVP, err
}
cer.appID = app.ID()
return nil, nil
}
// sanityCheck ensures mandatory AVPs are present.
func (cer *CER) sanityCheck() error {
if len(cer.OriginHost) == 0 {
return ErrMissingOriginHost
}
if len(cer.OriginRealm) == 0 {
return ErrMissingOriginRealm
}
return nil
}
// Applications return a list of supported Application IDs.
func (cer *CER) Applications() []uint32 {
return cer.appID
}