@@ -46,7 +46,9 @@ export class Chunk {
4646 }
4747
4848 get bytes ( ) {
49- if ( ! this . body ) throw new Error ( ) ;
49+ if ( ! this . body ) {
50+ throw new Error ( "Chunk body is undefined" ) ;
51+ }
5052
5153 const header = Buffer . alloc ( 4 ) ;
5254 header . writeUInt8 ( this . type , 0 ) ;
@@ -60,6 +62,17 @@ export class Chunk {
6062 ] ) ;
6163 return data ;
6264 }
65+
66+ static parse ( data : Buffer ) {
67+ if ( data . length < 4 ) {
68+ throw new Error ( "Chunk header length is less than 4 bytes" ) ;
69+ }
70+ const type = data . readUInt8 ( 0 ) ;
71+ const flags = data . readUInt8 ( 1 ) ;
72+ const length = data . readUInt16BE ( 2 ) ;
73+ const body = data . subarray ( 4 , length ) ;
74+ return { type, flags, length, body } ;
75+ }
6376}
6477
6578export class BaseInitChunk extends Chunk {
@@ -484,7 +497,7 @@ function padL(l: number) {
484497function encodeParams ( params : [ number , Buffer ] [ ] ) {
485498 let body = Buffer . from ( "" ) ;
486499 let padding = Buffer . from ( "" ) ;
487- params . forEach ( ( [ type , value ] ) => {
500+ for ( const [ type , value ] of params ) {
488501 const length = value . length + 4 ;
489502 const paramHeader = Buffer . alloc ( 4 ) ;
490503 paramHeader . writeUInt16BE ( type , 0 ) ;
@@ -493,7 +506,7 @@ function encodeParams(params: [number, Buffer][]) {
493506 padding = Buffer . concat (
494507 [ ...Array ( padL ( length ) ) ] . map ( ( ) => Buffer . from ( "\x00" ) ) ,
495508 ) ;
496- } ) ;
509+ }
497510 return body ;
498511}
499512
@@ -509,6 +522,20 @@ export function decodeParams(body: Buffer): [number, Buffer][] {
509522 return params ;
510523}
511524
525+ export const parseChunk = ( data : Buffer ) => {
526+ const { type, flags, length, body } = Chunk . parse ( data ) ;
527+
528+ const ChunkClass = CHUNK_BY_TYPE [ type . toString ( ) ] ;
529+ if ( ! ChunkClass ) {
530+ throw new Error ( "unknown" ) ;
531+ }
532+
533+ return {
534+ chunk : new ChunkClass ( flags , body ) ,
535+ length,
536+ } ;
537+ } ;
538+
512539export function parsePacket ( data : Buffer ) : [ number , number , number , Chunk [ ] ] {
513540 if ( data . length < 12 )
514541 throw new Error ( "SCTP packet length is less than 12 bytes" ) ;
@@ -532,17 +559,9 @@ export function parsePacket(data: Buffer): [number, number, number, Chunk[]] {
532559 const chunks : Chunk [ ] = [ ] ;
533560 let pos = 12 ;
534561 while ( pos + 4 <= data . length ) {
535- const chunkType = data . readUInt8 ( pos ) ;
536- const chunkFlags = data . readUInt8 ( pos + 1 ) ;
537- const chunkLength = data . readUInt16BE ( pos + 2 ) ;
538- const chunkBody = data . slice ( pos + 4 , pos + chunkLength ) ;
539- const ChunkClass = CHUNK_BY_TYPE [ chunkType . toString ( ) ] ;
540- if ( ChunkClass ) {
541- chunks . push ( new ChunkClass ( chunkFlags , chunkBody ) ) ;
542- } else {
543- throw new Error ( "unknown" ) ;
544- }
545- pos += chunkLength + padL ( chunkLength ) ;
562+ const { length, chunk } = parseChunk ( data . subarray ( pos ) ) ;
563+ chunks . push ( chunk ) ;
564+ pos += length + padL ( length ) ;
546565 }
547566 return [ sourcePort , destinationPort , verificationTag , chunks ] ;
548567}
0 commit comments