@@ -252,6 +252,105 @@ func TestAccountingRequestAuth(t *testing.T) {
252252 }
253253}
254254
255+ // VALIDATES: AC-3/AC-4 -- CoA-Request (code 43) round-trips through encode/decode.
256+ func TestCoARequestRoundTrip (t * testing.T ) {
257+ pkt := & Packet {
258+ Code : CodeCoARequest ,
259+ Identifier : 10 ,
260+ Attrs : []Attr {
261+ {Type : AttrAcctSessionID , Value : AttrString ("sess-001" )},
262+ {Type : AttrFilterID , Value : AttrString ("10mbit" )},
263+ },
264+ }
265+
266+ buf := make ([]byte , MaxPacketLen )
267+ n , err := pkt .EncodeTo (buf , 0 )
268+ if err != nil {
269+ t .Fatal (err )
270+ }
271+
272+ // Set proper CoA authenticator.
273+ secret := []byte ("coa-secret" )
274+ auth := AccountingRequestAuth (buf , n , secret )
275+ copy (buf [4 :4 + AuthenticatorLen ], auth [:])
276+
277+ decoded , err := Decode (buf [:n ])
278+ if err != nil {
279+ t .Fatal (err )
280+ }
281+ if decoded .Code != CodeCoARequest {
282+ t .Errorf ("code: got %d, want %d" , decoded .Code , CodeCoARequest )
283+ }
284+ sessID := decoded .FindAttr (AttrAcctSessionID )
285+ if string (sessID ) != "sess-001" {
286+ t .Errorf ("Acct-Session-Id: got %q, want %q" , sessID , "sess-001" )
287+ }
288+ }
289+
290+ // VALIDATES: AC-6/AC-7 -- Disconnect-Request (code 40) round-trips.
291+ func TestDisconnectRequestRoundTrip (t * testing.T ) {
292+ pkt := & Packet {
293+ Code : CodeDisconnectRequest ,
294+ Identifier : 20 ,
295+ Attrs : []Attr {
296+ {Type : AttrAcctSessionID , Value : AttrString ("sess-002" )},
297+ },
298+ }
299+
300+ buf := make ([]byte , MaxPacketLen )
301+ n , err := pkt .EncodeTo (buf , 0 )
302+ if err != nil {
303+ t .Fatal (err )
304+ }
305+
306+ decoded , err := Decode (buf [:n ])
307+ if err != nil {
308+ t .Fatal (err )
309+ }
310+ if decoded .Code != CodeDisconnectRequest {
311+ t .Errorf ("code: got %d, want %d" , decoded .Code , CodeDisconnectRequest )
312+ }
313+ }
314+
315+ // VALIDATES: AC-3 -- CoA request authenticator verification.
316+ func TestVerifyCoARequestAuth (t * testing.T ) {
317+ secret := []byte ("coa-test-secret" )
318+ pkt := & Packet {
319+ Code : CodeCoARequest ,
320+ Identifier : 5 ,
321+ Attrs : []Attr {
322+ {Type : AttrAcctSessionID , Value : AttrString ("sess-100" )},
323+ },
324+ }
325+
326+ buf := make ([]byte , MaxPacketLen )
327+ n , err := pkt .EncodeTo (buf , 0 )
328+ if err != nil {
329+ t .Fatal (err )
330+ }
331+
332+ // Set correct authenticator.
333+ auth := AccountingRequestAuth (buf , n , secret )
334+ copy (buf [4 :4 + AuthenticatorLen ], auth [:])
335+
336+ if ! VerifyCoARequestAuth (buf [:n ], secret ) {
337+ t .Error ("valid CoA auth should verify" )
338+ }
339+
340+ // Corrupt one byte.
341+ buf [4 ]++
342+ if VerifyCoARequestAuth (buf [:n ], secret ) {
343+ t .Error ("corrupted CoA auth should fail verification" )
344+ }
345+ }
346+
347+ // VALIDATES: AC-4 -- invalid authenticator on short packet.
348+ func TestVerifyCoARequestAuthTooShort (t * testing.T ) {
349+ if VerifyCoARequestAuth (make ([]byte , 10 ), []byte ("secret" )) {
350+ t .Error ("short packet should fail verification" )
351+ }
352+ }
353+
255354func TestEncodeAtOffset (t * testing.T ) {
256355 pkt := & Packet {
257356 Code : CodeAccessRequest ,
0 commit comments