Repository: pion/sctp
Pull request #259 (2023-01-13 00:39:35)

Expose error values
Make it possible to compare errors using `errors.Is()`.

#### Reference issue
Related #251 


codecov[bot]: # [Codecov](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion) Report
Base: **80.87**% // Head: **80.67**% // Decreases project coverage by **`-0.19%`** :warning:
> Coverage data is based on head [(`c6cc55b`)](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion) compared to base [(`7ca78e8`)](https://codecov.io/gh/pion/sctp/commit/7ca78e8c75c32586ac2e47e3bc0727a695a69a10?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion).
> Patch coverage: 28.15% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #259      +/-   ##
==========================================
- Coverage   80.87%   80.67%   -0.20%     
==========================================
  Files          48       48              
  Lines        4032     4032              
==========================================
- Hits         3261     3253       -8     
- Misses        629      636       +7     
- Partials      142      143       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| go | `80.67% <28.15%> (-0.20%)` | :arrow_down: |
| wasm | `67.46% <19.41%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion) | Coverage Δ | |
|---|---|---|
| [chunk\_abort.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfYWJvcnQuZ28=) | `50.00% <0.00%> (ø)` | |
| [chunk\_cookie\_ack.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfY29va2llX2Fjay5nbw==) | `60.00% <0.00%> (ø)` | |
| [chunk\_cookie\_echo.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfY29va2llX2VjaG8uZ28=) | `62.50% <0.00%> (ø)` | |
| [chunk\_error.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfZXJyb3IuZ28=) | `50.00% <0.00%> (ø)` | |
| [chunk\_heartbeat.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfaGVhcnRiZWF0Lmdv) | `0.00% <0.00%> (ø)` | |
| [chunk\_heartbeat\_ack.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfaGVhcnRiZWF0X2Fjay5nbw==) | `0.00% <0.00%> (ø)` | |
| [chunk\_init.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfaW5pdC5nbw==) | `36.36% <0.00%> (ø)` | |
| [chunk\_init\_ack.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfaW5pdF9hY2suZ28=) | `37.50% <0.00%> (ø)` | |
| [chunk\_init\_common.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfaW5pdF9jb21tb24uZ28=) | `65.51% <0.00%> (ø)` | |
| [chunk\_selective\_ack.go](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#diff-Y2h1bmtfc2VsZWN0aXZlX2Fjay5nbw==) | `66.66% <0.00%> (ø)` | |
| ... and [20 more](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion) | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/pion/sctp/pull/259?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion).


Patch:
diff --git a/association.go b/association.go
index 91b92fc..fb0f9ad 100644
--- a/association.go
+++ b/association.go
@@ -17,28 +17,30 @@ import (
 )
 
 // Use global random generator to properly seed by crypto grade random.
+var globalMathRandomGenerator = randutil.NewMathRandomGenerator() // nolint:gochecknoglobals
+
+// Association errors
 var (
-	globalMathRandomGenerator        = randutil.NewMathRandomGenerator() // nolint:gochecknoglobals
-	errChunk                         = errors.New("abort chunk, with following errors")
-	errShutdownNonEstablished        = errors.New("shutdown called in non-established state")
-	errAssociationClosedBeforeConn   = errors.New("association closed before connecting")
-	errSilentlyDiscard               = errors.New("silently discard")
-	errInitNotStoredToSend           = errors.New("the init not stored to send")
-	errCookieEchoNotStoredToSend     = errors.New("cookieEcho not stored to send")
-	errSCTPPacketSourcePortZero      = errors.New("sctp packet must not have a source port of 0")
-	errSCTPPacketDestinationPortZero = errors.New("sctp packet must not have a destination port of 0")
-	errInitChunkBundled              = errors.New("init chunk must not be bundled with any other chunk")
-	errInitChunkVerifyTagNotZero     = errors.New("init chunk expects a verification tag of 0 on the packet when out-of-the-blue")
-	errHandleInitState               = errors.New("todo: handle Init when in state")
-	errInitAckNoCookie               = errors.New("no cookie in InitAck")
-	errInflightQueueTSNPop           = errors.New("unable to be popped from inflight queue TSN")
-	errTSNRequestNotExist            = errors.New("requested non-existent TSN")
-	errResetPacketInStateNotExist    = errors.New("sending reset packet in non-established state")
-	errParamterType                  = errors.New("unexpected parameter type")
-	errPayloadDataStateNotExist      = errors.New("sending payload data in non-established state")
-	errChunkTypeUnhandled            = errors.New("unhandled chunk type")
-	errHandshakeInitAck              = errors.New("handshake failed (INIT ACK)")
-	errHandshakeCookieEcho           = errors.New("handshake failed (COOKIE ECHO)")
+	ErrChunk                         = errors.New("abort chunk, with following errors")
+	ErrShutdownNonEstablished        = errors.New("shutdown called in non-established state")
+	ErrAssociationClosedBeforeConn   = errors.New("association closed before connecting")
+	ErrSilentlyDiscard               = errors.New("silently discard")
+	ErrInitNotStoredToSend           = errors.New("the init not stored to send")
+	ErrCookieEchoNotStoredToSend     = errors.New("cookieEcho not stored to send")
+	ErrSCTPPacketSourcePortZero      = errors.New("sctp packet must not have a source port of 0")
+	ErrSCTPPacketDestinationPortZero = errors.New("sctp packet must not have a destination port of 0")
+	ErrInitChunkBundled              = errors.New("init chunk must not be bundled with any other chunk")
+	ErrInitChunkVerifyTagNotZero     = errors.New("init chunk expects a verification tag of 0 on the packet when out-of-the-blue")
+	ErrHandleInitState               = errors.New("todo: handle Init when in state")
+	ErrInitAckNoCookie               = errors.New("no cookie in InitAck")
+	ErrInflightQueueTSNPop           = errors.New("unable to be popped from inflight queue TSN")
+	ErrTSNRequestNotExist            = errors.New("requested non-existent TSN")
+	ErrResetPacketInStateNotExist    = errors.New("sending reset packet in non-established state")
+	ErrParamterType                  = errors.New("unexpected parameter type")
+	ErrPayloadDataStateNotExist      = errors.New("sending payload data in non-established state")
+	ErrChunkTypeUnhandled            = errors.New("unhandled chunk type")
+	ErrHandshakeInitAck              = errors.New("handshake failed (INIT ACK)")
+	ErrHandshakeCookieEcho           = errors.New("handshake failed (COOKIE ECHO)")
 )
 
 const (
@@ -246,7 +248,7 @@ func Server(config Config) (*Association, error) {
 		}
 		return a, nil
 	case <-a.readLoopCloseCh:
-		return nil, errAssociationClosedBeforeConn
+		return nil, ErrAssociationClosedBeforeConn
 	}
 }
 
@@ -262,7 +264,7 @@ func Client(config Config) (*Association, error) {
 		}
 		return a, nil
 	case <-a.readLoopCloseCh:
-		return nil, errAssociationClosedBeforeConn
+		return nil, ErrAssociationClosedBeforeConn
 	}
 }
 
@@ -310,7 +312,7 @@ func createAssociation(config Config) *Association {
 		handshakeCompletedCh:    make(chan error),
 		cumulativeTSNAckPoint:   tsn - 1,
 		advancedPeerTSNAckPoint: tsn - 1,
-		silentError:             errSilentlyDiscard,
+		silentError:             ErrSilentlyDiscard,
 		stats:                   &associationStats{},
 		log:                     config.LoggerFactory.NewLogger("sctp"),
 	}
@@ -366,7 +368,7 @@ func (a *Association) init(isClient bool) {
 func (a *Association) sendInit() error {
 	a.log.Debugf("[%s] sending INIT", a.name)
 	if a.storedInit == nil {
-		return errInitNotStoredToSend
+		return ErrInitNotStoredToSend
 	}
 
 	outbound := &packet{}
@@ -387,7 +389,7 @@ func (a *Association) sendInit() error {
 // caller must hold a.lock
 func (a *Association) sendCookieEcho() error {
 	if a.storedCookieEcho == nil {
-		return errCookieEchoNotStoredToSend
+		return ErrCookieEchoNotStoredToSend
 	}
 
 	a.log.Debugf("[%s] sending COOKIE-ECHO", a.name)
@@ -413,7 +415,7 @@ func (a *Association) Shutdown(ctx context.Context) error {
 	state := a.getState()
 
 	if state != established {
-		return fmt.Errorf("%w: shutdown %s", errShutdownNonEstablished, a.name)
+		return fmt.Errorf("%w: shutdown %s", ErrShutdownNonEstablished, a.name)
 	}
 
 	// Attempt a graceful shutdown.
@@ -930,7 +932,7 @@ func checkPacket(p *packet) error {
 	// identify the association to which this packet belongs.  The port
 	// number 0 MUST NOT be used.
 	if p.sourcePort == 0 {
-		return errSCTPPacketSourcePortZero
+		return ErrSCTPPacketSourcePortZero
 	}
 
 	// This is the SCTP port number to which this packet is destined.
@@ -938,7 +940,7 @@ func checkPacket(p *packet) error {
 	// SCTP packet to the correct receiving endpoint/application.  The
 	// port number 0 MUST NOT be used.
 	if p.destinationPort == 0 {
-		return errSCTPPacketDestinationPortZero
+		return ErrSCTPPacketDestinationPortZero
 	}
 
 	// Check values on the packet that are specific to a particular chunk type
@@ -949,13 +951,13 @@ func checkPacket(p *packet) error {
 			// They MUST be the only chunks present in the SCTP packets that carry
 			// them.
 			if len(p.chunks) != 1 {
-				return errInitChunkBundled
+				return ErrInitChunkBundled
 			}
 
 			// A packet containing an INIT chunk MUST have a zero Verification
 			// Tag.
 			if p.verificationTag != 0 {
-				return errInitChunkVerifyTagNotZero
+				return ErrInitChunkVerifyTagNotZero
 			}
 		}
 	}
@@ -1037,7 +1039,7 @@ func (a *Association) handleInit(p *packet, i *chunkInit) ([]*packet, error) {
 	if state != closed && state != cookieWait && state != cookieEchoed {
 		// 5.2.2.  Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
 		//        COOKIE-WAIT, and SHUTDOWN-ACK-SENT
-		return nil, fmt.Errorf("%w: %s", errHandleInitState, getAssociationStateString(state))
+		return nil, fmt.Errorf("%w: %s", ErrHandleInitState, getAssociationStateString(state))
 	}
 
 	// Should we be setting any of these permanently until we've ACKed further?
@@ -1153,7 +1155,7 @@ func (a *Association) handleInitAck(p *packet, i *chunkInitAck) error {
 		a.log.Warnf("[%s] not using ForwardTSN (on initAck)", a.name)
 	}
 	if cookieParam == nil {
-		return errInitAckNoCookie
+		return ErrInitAckNoCookie
 	}
 
 	a.storedCookieEcho = &chunkCookieEcho{}
@@ -1415,7 +1417,7 @@ func (a *Association) processSelectiveAck(d *chunkSelectiveAck) (map[uint16]int,
 	for i := a.cumulativeTSNAckPoint + 1; sna32LTE(i, d.cumulativeTSNAck); i++ {
 		c, ok := a.inflightQueue.pop(i)
 		if !ok {
-			return nil, 0, fmt.Errorf("%w: %v", errInflightQueueTSNPop, i)
+			return nil, 0, fmt.Errorf("%w: %v", ErrInflightQueueTSNPop, i)
 		}
 
 		if !c.acked {
@@ -1470,7 +1472,7 @@ func (a *Association) processSelectiveAck(d *chunkSelectiveAck) (map[uint16]int,
 			tsn := d.cumulativeTSNAck + uint32(i)
 			c, ok := a.inflightQueue.get(tsn)
 			if !ok {
-				return nil, 0, fmt.Errorf("%w: %v", errTSNRequestNotExist, tsn)
+				return nil, 0, fmt.Errorf("%w: %v", ErrTSNRequestNotExist, tsn)
 			}
 
 			if !c.acked {
@@ -1586,7 +1588,7 @@ func (a *Association) processFastRetransmission(cumTSNAckPoint, htna uint32, cum
 		for tsn := cumTSNAckPoint + 1; sna32LT(tsn, maxTSN); tsn++ {
 			c, ok := a.inflightQueue.get(tsn)
 			if !ok {
-				return fmt.Errorf("%w: %v", errTSNRequestNotExist, tsn)
+				return fmt.Errorf("%w: %v", ErrTSNRequestNotExist, tsn)
 			}
 			if !c.acked && !c.abandoned() && c.missIndicator < 3 {
 				c.missIndicator++
@@ -1805,7 +1807,7 @@ func (a *Association) handleAbort(c *chunkAbort) error {
 
 	_ = a.close()
 
-	return fmt.Errorf("[%s] %w: %s", a.name, errChunk, errStr)
+	return fmt.Errorf("[%s] %w: %s", a.name, ErrChunk, errStr)
 }
 
 // createForwardTSN generates ForwardTSN chunk.
@@ -1963,7 +1965,7 @@ func (a *Association) sendResetRequest(streamIdentifier uint16) error {
 
 	state := a.getState()
 	if state != established {
-		return fmt.Errorf("%w: state=%s", errResetPacketInStateNotExist,
+		return fmt.Errorf("%w: state=%s", ErrResetPacketInStateNotExist,
 			getAssociationStateString(state))
 	}
 
@@ -2001,7 +2003,7 @@ func (a *Association) handleReconfigParam(raw param) (*packet, error) {
 		}
 		return nil, nil //nolint:nilnil
 	default:
-		return nil, fmt.Errorf("%w: %t", errParamterType, p)
+		return nil, fmt.Errorf("%w: %t", ErrParamterType, p)
 	}
 }
 
@@ -2162,7 +2164,7 @@ func (a *Association) sendPayloadData(chunks []*chunkPayloadData) error {
 
 	state := a.getState()
 	if state != established {
-		return fmt.Errorf("%w: state=%s", errPayloadDataStateNotExist,
+		return fmt.Errorf("%w: state=%s", ErrPayloadDataStateNotExist,
 			getAssociationStateString(state))
 	}
 
@@ -2367,7 +2369,7 @@ func (a *Association) handleChunk(p *packet, c chunk) error {
 		err = a.handleShutdownComplete(c)
 
 	default:
-		err = errChunkTypeUnhandled
+		err = ErrChunkTypeUnhandled
 	}
 
 	// Log and return, the only condition that is fatal is a ABORT chunk
@@ -2495,13 +2497,13 @@ func (a *Association) onRetransmissionFailure(id int) {
 
 	if id == timerT1Init {
 		a.log.Errorf("[%s] retransmission failure: T1-init", a.name)
-		a.handshakeCompletedCh <- errHandshakeInitAck
+		a.handshakeCompletedCh <- ErrHandshakeInitAck
 		return
 	}
 
 	if id == timerT1Cookie {
 		a.log.Errorf("[%s] retransmission failure: T1-cookie", a.name)
-		a.handshakeCompletedCh <- errHandshakeCookieEcho
+		a.handshakeCompletedCh <- ErrHandshakeCookieEcho
 		return
 	}
 
diff --git a/chunk_abort.go b/chunk_abort.go
index 9288412..702f82d 100644
--- a/chunk_abort.go
+++ b/chunk_abort.go
@@ -31,9 +31,10 @@ type chunkAbort struct {
 	errorCauses []errorCause
 }
 
+// Abort chunk errors
 var (
-	errChunkTypeNotAbort     = errors.New("ChunkType is not of type ABORT")
-	errBuildAbortChunkFailed = errors.New("failed build Abort Chunk")
+	ErrChunkTypeNotAbort     = errors.New("ChunkType is not of type ABORT")
+	ErrBuildAbortChunkFailed = errors.New("failed build Abort Chunk")
 )
 
 func (a *chunkAbort) unmarshal(raw []byte) error {
@@ -42,7 +43,7 @@ func (a *chunkAbort) unmarshal(raw []byte) error {
 	}
 
 	if a.typ != ctAbort {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotAbort, a.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotAbort, a.typ.String())
 	}
 
 	offset := chunkHeaderSize
@@ -53,7 +54,7 @@ func (a *chunkAbort) unmarshal(raw []byte) error {
 
 		e, err := buildErrorCause(raw[offset:])
 		if err != nil {
-			return fmt.Errorf("%w: %v", errBuildAbortChunkFailed, err)
+			return fmt.Errorf("%w: %v", ErrBuildAbortChunkFailed, err)
 		}
 
 		offset += int(e.length())
diff --git a/chunk_cookie_ack.go b/chunk_cookie_ack.go
index 742529c..0bbf290 100644
--- a/chunk_cookie_ack.go
+++ b/chunk_cookie_ack.go
@@ -18,7 +18,10 @@ type chunkCookieAck struct {
 	chunkHeader
 }
 
-var errChunkTypeNotCookieAck = errors.New("ChunkType is not of type COOKIEACK")
+// Cookie ack chunk errors
+var (
+	ErrChunkTypeNotCookieAck = errors.New("ChunkType is not of type COOKIEACK")
+)
 
 func (c *chunkCookieAck) unmarshal(raw []byte) error {
 	if err := c.chunkHeader.unmarshal(raw); err != nil {
@@ -26,7 +29,7 @@ func (c *chunkCookieAck) unmarshal(raw []byte) error {
 	}
 
 	if c.typ != ctCookieAck {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotCookieAck, c.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotCookieAck, c.typ.String())
 	}
 
 	return nil
diff --git a/chunk_cookie_echo.go b/chunk_cookie_echo.go
index 3aaced3..e8548ee 100644
--- a/chunk_cookie_echo.go
+++ b/chunk_cookie_echo.go
@@ -22,7 +22,10 @@ type chunkCookieEcho struct {
 	cookie []byte
 }
 
-var errChunkTypeNotCookieEcho = errors.New("ChunkType is not of type COOKIEECHO")
+// Cookie echo chunk errors
+var (
+	ErrChunkTypeNotCookieEcho = errors.New("ChunkType is not of type COOKIEECHO")
+)
 
 func (c *chunkCookieEcho) unmarshal(raw []byte) error {
 	if err := c.chunkHeader.unmarshal(raw); err != nil {
@@ -30,7 +33,7 @@ func (c *chunkCookieEcho) unmarshal(raw []byte) error {
 	}
 
 	if c.typ != ctCookieEcho {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotCookieEcho, c.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotCookieEcho, c.typ.String())
 	}
 	c.cookie = c.raw
 
diff --git a/chunk_error.go b/chunk_error.go
index d58d752..ec03397 100644
--- a/chunk_error.go
+++ b/chunk_error.go
@@ -38,9 +38,10 @@ type chunkError struct {
 	errorCauses []errorCause
 }
 
+// Error chunk errors
 var (
-	errChunkTypeNotCtError   = errors.New("ChunkType is not of type ctError")
-	errBuildErrorChunkFailed = errors.New("failed build Error Chunk")
+	ErrChunkTypeNotCtError   = errors.New("ChunkType is not of type ctError")
+	ErrBuildErrorChunkFailed = errors.New("failed build Error Chunk")
 )
 
 func (a *chunkError) unmarshal(raw []byte) error {
@@ -49,7 +50,7 @@ func (a *chunkError) unmarshal(raw []byte) error {
 	}
 
 	if a.typ != ctError {
-		return fmt.Errorf("%w, actually is %s", errChunkTypeNotCtError, a.typ.String())
+		return fmt.Errorf("%w, actually is %s", ErrChunkTypeNotCtError, a.typ.String())
 	}
 
 	offset := chunkHeaderSize
@@ -60,7 +61,7 @@ func (a *chunkError) unmarshal(raw []byte) error {
 
 		e, err := buildErrorCause(raw[offset:])
 		if err != nil {
-			return fmt.Errorf("%w: %v", errBuildErrorChunkFailed, err)
+			return fmt.Errorf("%w: %v", ErrBuildErrorChunkFailed, err)
 		}
 
 		offset += int(e.length())
diff --git a/chunk_forward_tsn.go b/chunk_forward_tsn.go
index 8f04d93..abadd6d 100644
--- a/chunk_forward_tsn.go
+++ b/chunk_forward_tsn.go
@@ -43,9 +43,10 @@ const (
 	forwardTSNStreamLength = 4
 )
 
+// Forward TSN chunk errors
 var (
-	errMarshalStreamFailed = errors.New("failed to marshal stream")
-	errChunkTooShort       = errors.New("chunk too short")
+	ErrMarshalStreamFailed = errors.New("failed to marshal stream")
+	ErrChunkTooShort       = errors.New("chunk too short")
 )
 
 func (c *chunkForwardTSN) unmarshal(raw []byte) error {
@@ -54,7 +55,7 @@ func (c *chunkForwardTSN) unmarshal(raw []byte) error {
 	}
 
 	if len(c.raw) < newCumulativeTSNLength {
-		return errChunkTooShort
+		return ErrChunkTooShort
 	}
 
 	c.newCumulativeTSN = binary.BigEndian.Uint32(c.raw[0:])
@@ -65,7 +66,7 @@ func (c *chunkForwardTSN) unmarshal(raw []byte) error {
 		s := chunkForwardTSNStream{}
 
 		if err := s.unmarshal(c.raw[offset:]); err != nil {
-			return fmt.Errorf("%w: %v", errMarshalStreamFailed, err)
+			return fmt.Errorf("%w: %v", ErrMarshalStreamFailed, err)
 		}
 
 		c.streams = append(c.streams, s)
@@ -84,7 +85,7 @@ func (c *chunkForwardTSN) marshal() ([]byte, error) {
 	for _, s := range c.streams {
 		b, err := s.marshal()
 		if err != nil {
-			return nil, fmt.Errorf("%w: %v", errMarshalStreamFailed, err)
+			return nil, fmt.Errorf("%w: %v", ErrMarshalStreamFailed, err)
 		}
 		out = append(out, b...)
 	}
@@ -129,7 +130,7 @@ func (s *chunkForwardTSNStream) length() int {
 
 func (s *chunkForwardTSNStream) unmarshal(raw []byte) error {
 	if len(raw) < forwardTSNStreamLength {
-		return errChunkTooShort
+		return ErrChunkTooShort
 	}
 	s.identifier = binary.BigEndian.Uint16(raw[0:])
 	s.sequence = binary.BigEndian.Uint16(raw[2:])
diff --git a/chunk_heartbeat.go b/chunk_heartbeat.go
index 7db97cd..abbd4fc 100644
--- a/chunk_heartbeat.go
+++ b/chunk_heartbeat.go
@@ -38,36 +38,37 @@ type chunkHeartbeat struct {
 	params []param
 }
 
+// Heartbeat chunk errors
 var (
-	errChunkTypeNotHeartbeat      = errors.New("ChunkType is not of type HEARTBEAT")
-	errHeartbeatNotLongEnoughInfo = errors.New("heartbeat is not long enough to contain Heartbeat Info")
-	errParseParamTypeFailed       = errors.New("failed to parse param type")
-	errHeartbeatParam             = errors.New("heartbeat should only have HEARTBEAT param")
-	errHeartbeatChunkUnmarshal    = errors.New("failed unmarshalling param in Heartbeat Chunk")
+	ErrChunkTypeNotHeartbeat      = errors.New("ChunkType is not of type HEARTBEAT")
+	ErrHeartbeatNotLongEnoughInfo = errors.New("heartbeat is not long enough to contain Heartbeat Info")
+	ErrParseParamTypeFailed       = errors.New("failed to parse param type")
+	ErrHeartbeatParam             = errors.New("heartbeat should only have HEARTBEAT param")
+	ErrHeartbeatChunkUnmarshal    = errors.New("failed unmarshalling param in Heartbeat Chunk")
 )
 
 func (h *chunkHeartbeat) unmarshal(raw []byte) error {
 	if err := h.chunkHeader.unmarshal(raw); err != nil {
 		return err
 	} else if h.typ != ctHeartbeat {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotHeartbeat, h.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotHeartbeat, h.typ.String())
 	}
 
 	if len(raw) <= chunkHeaderSize {
-		return fmt.Errorf("%w: %d", errHeartbeatNotLongEnoughInfo, len(raw))
+		return fmt.Errorf("%w: %d", ErrHeartbeatNotLongEnoughInfo, len(raw))
 	}
 
 	pType, err := parseParamType(raw[chunkHeaderSize:])
 	if err != nil {
-		return fmt.Errorf("%w: %v", errParseParamTypeFailed, err)
+		return fmt.Errorf("%w: %v", ErrParseParamTypeFailed, err)
 	}
 	if pType != heartbeatInfo {
-		return fmt.Errorf("%w: instead have %s", errHeartbeatParam, pType.String())
+		return fmt.Errorf("%w: instead have %s", ErrHeartbeatParam, pType.String())
 	}
 
 	p, err := buildParam(pType, raw[chunkHeaderSize:])
 	if err != nil {
-		return fmt.Errorf("%w: %v", errHeartbeatChunkUnmarshal, err)
+		return fmt.Errorf("%w: %v", ErrHeartbeatChunkUnmarshal, err)
 	}
 	h.params = append(h.params, p)
 
@@ -75,7 +76,7 @@ func (h *chunkHeartbeat) unmarshal(raw []byte) error {
 }
 
 func (h *chunkHeartbeat) Marshal() ([]byte, error) {
-	return nil, errUnimplemented
+	return nil, ErrUnimplemented
 }
 
 func (h *chunkHeartbeat) check() (abort bool, err error) {
diff --git a/chunk_heartbeat_ack.go b/chunk_heartbeat_ack.go
index feb822c..9e68c71 100644
--- a/chunk_heartbeat_ack.go
+++ b/chunk_heartbeat_ack.go
@@ -38,34 +38,35 @@ type chunkHeartbeatAck struct {
 	params []param
 }
 
+// Heartbeat ack chunk errors
 var (
-	errUnimplemented                = errors.New("unimplemented")
-	errHeartbeatAckParams           = errors.New("heartbeat Ack must have one param")
-	errHeartbeatAckNotHeartbeatInfo = errors.New("heartbeat Ack must have one param, and it should be a HeartbeatInfo")
-	errHeartbeatAckMarshalParam     = errors.New("unable to marshal parameter for Heartbeat Ack")
+	ErrUnimplemented                = errors.New("unimplemented")
+	ErrHeartbeatAckParams           = errors.New("heartbeat Ack must have one param")
+	ErrHeartbeatAckNotHeartbeatInfo = errors.New("heartbeat Ack must have one param, and it should be a HeartbeatInfo")
+	ErrHeartbeatAckMarshalParam     = errors.New("unable to marshal parameter for Heartbeat Ack")
 )
 
 func (h *chunkHeartbeatAck) unmarshal(raw []byte) error {
-	return errUnimplemented
+	return ErrUnimplemented
 }
 
 func (h *chunkHeartbeatAck) marshal() ([]byte, error) {
 	if len(h.params) != 1 {
-		return nil, errHeartbeatAckParams
+		return nil, ErrHeartbeatAckParams
 	}
 
 	switch h.params[0].(type) {
 	case *paramHeartbeatInfo:
 		// ParamHeartbeatInfo is valid
 	default:
-		return nil, errHeartbeatAckNotHeartbeatInfo
+		return nil, ErrHeartbeatAckNotHeartbeatInfo
 	}
 
 	out := make([]byte, 0)
 	for idx, p := range h.params {
 		pp, err := p.marshal()
 		if err != nil {
-			return nil, fmt.Errorf("%w: %v", errHeartbeatAckMarshalParam, err)
+			return nil, fmt.Errorf("%w: %v", ErrHeartbeatAckMarshalParam, err)
 		}
 
 		out = append(out, pp...)
diff --git a/chunk_init.go b/chunk_init.go
index 8a2a1cd..75341d8 100644
--- a/chunk_init.go
+++ b/chunk_init.go
@@ -24,16 +24,17 @@ type chunkInit struct {
 	chunkInitCommon
 }
 
+// Init chunk errors
 var (
-	errChunkTypeNotTypeInit          = errors.New("ChunkType is not of type INIT")
-	errChunkValueNotLongEnough       = errors.New("chunk Value isn't long enough for mandatory parameters exp")
-	errChunkTypeInitFlagZero         = errors.New("ChunkType of type INIT flags must be all 0")
-	errChunkTypeInitUnmarshalFailed  = errors.New("failed to unmarshal INIT body")
-	errChunkTypeInitMarshalFailed    = errors.New("failed marshaling INIT common data")
-	errChunkTypeInitInitateTagZero   = errors.New("ChunkType of type INIT ACK InitiateTag must not be 0")
-	errInitInboundStreamRequestZero  = errors.New("INIT ACK inbound stream request must be > 0")
-	errInitOutboundStreamRequestZero = errors.New("INIT ACK outbound stream request must be > 0")
-	errInitAdvertisedReceiver1500    = errors.New("INIT ACK Advertised Receiver Window Credit (a_rwnd) must be >= 1500")
+	ErrChunkTypeNotTypeInit          = errors.New("ChunkType is not of type INIT")
+	ErrChunkValueNotLongEnough       = errors.New("chunk Value isn't long enough for mandatory parameters exp")
+	ErrChunkTypeInitFlagZero         = errors.New("ChunkType of type INIT flags must be all 0")
+	ErrChunkTypeInitUnmarshalFailed  = errors.New("failed to unmarshal INIT body")
+	ErrChunkTypeInitMarshalFailed    = errors.New("failed marshaling INIT common data")
+	ErrChunkTypeInitInitateTagZero   = errors.New("ChunkType of type INIT ACK InitiateTag must not be 0")
+	ErrInitInboundStreamRequestZero  = errors.New("INIT ACK inbound stream request must be > 0")
+	ErrInitOutboundStreamRequestZero = errors.New("INIT ACK outbound stream request must be > 0")
+	ErrInitAdvertisedReceiver1500    = errors.New("INIT ACK Advertised Receiver Window Credit (a_rwnd) must be >= 1500")
 )
 
 func (i *chunkInit) unmarshal(raw []byte) error {
@@ -42,20 +43,20 @@ func (i *chunkInit) unmarshal(raw []byte) error {
 	}
 
 	if i.typ != ctInit {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotTypeInit, i.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotTypeInit, i.typ.String())
 	} else if len(i.raw) < initChunkMinLength {
-		return fmt.Errorf("%w: %d actual: %d", errChunkValueNotLongEnough, initChunkMinLength, len(i.raw))
+		return fmt.Errorf("%w: %d actual: %d", ErrChunkValueNotLongEnough, initChunkMinLength, len(i.raw))
 	}
 
 	// The Chunk Flags field in INIT is reserved, and all bits in it should
 	// be set to 0 by the sender and ignored by the receiver.  The sequence
 	// of parameters within an INIT can be processed in any order.
 	if i.flags != 0 {
-		return errChunkTypeInitFlagZero
+		return ErrChunkTypeInitFlagZero
 	}
 
 	if err := i.chunkInitCommon.unmarshal(i.raw); err != nil {
-		return fmt.Errorf("%w: %v", errChunkTypeInitUnmarshalFailed, err)
+		return fmt.Errorf("%w: %v", ErrChunkTypeInitUnmarshalFailed, err)
 	}
 
 	return nil
@@ -64,7 +65,7 @@ func (i *chunkInit) unmarshal(raw []byte) error {
 func (i *chunkInit) marshal() ([]byte, error) {
 	initShared, err := i.chunkInitCommon.marshal()
 	if err != nil {
-		return nil, fmt.Errorf("%w: %v", errChunkTypeInitMarshalFailed, err)
+		return nil, fmt.Errorf("%w: %v", ErrChunkTypeInitMarshalFailed, err)
 	}
 
 	i.chunkHeader.typ = ctInit
@@ -86,7 +87,7 @@ func (i *chunkInit) check() (abort bool, err error) {
 	// association by transmitting an ABORT.
 	if i.initiateTag == 0 {
 		abort = true
-		return abort, errChunkTypeInitInitateTagZero
+		return abort, ErrChunkTypeInitInitateTagZero
 	}
 
 	// Defines the maximum number of streams the sender of this INIT
@@ -101,7 +102,7 @@ func (i *chunkInit) check() (abort bool, err error) {
 	// the association.
 	if i.numInboundStreams == 0 {
 		abort = true
-		return abort, errInitInboundStreamRequestZero
+		return abort, ErrInitInboundStreamRequestZero
 	}
 
 	// Defines the number of outbound streams the sender of this INIT
@@ -113,7 +114,7 @@ func (i *chunkInit) check() (abort bool, err error) {
 
 	if i.numOutboundStreams == 0 {
 		abort = true
-		return abort, errInitOutboundStreamRequestZero
+		return abort, ErrInitOutboundStreamRequestZero
 	}
 
 	// An SCTP receiver MUST be able to receive a minimum of 1500 bytes in
@@ -122,7 +123,7 @@ func (i *chunkInit) check() (abort bool, err error) {
 	// ACK.
 	if i.advertisedReceiverWindowCredit < 1500 {
 		abort = true
-		return abort, errInitAdvertisedReceiver1500
+		return abort, ErrInitAdvertisedReceiver1500
 	}
 
 	return false, nil
diff --git a/chunk_init_ack.go b/chunk_init_ack.go
index 02a3344..ed6dd12 100644
--- a/chunk_init_ack.go
+++ b/chunk_init_ack.go
@@ -24,16 +24,17 @@ type chunkInitAck struct {
 	chunkInitCommon
 }
 
+// Init ack chunk errors
 var (
-	errChunkTypeNotInitAck              = errors.New("ChunkType is not of type INIT ACK")
-	errChunkNotLongEnoughForParams      = errors.New("chunk Value isn't long enough for mandatory parameters exp")
-	errChunkTypeInitAckFlagZero         = errors.New("ChunkType of type INIT ACK flags must be all 0")
-	errInitAckUnmarshalFailed           = errors.New("failed to unmarshal INIT body")
-	errInitCommonDataMarshalFailed      = errors.New("failed marshaling INIT common data")
-	errChunkTypeInitAckInitateTagZero   = errors.New("ChunkType of type INIT ACK InitiateTag must not be 0")
-	errInitAckInboundStreamRequestZero  = errors.New("INIT ACK inbound stream request must be > 0")
-	errInitAckOutboundStreamRequestZero = errors.New("INIT ACK outbound stream request must be > 0")
-	errInitAckAdvertisedReceiver1500    = errors.New("INIT ACK Advertised Receiver Window Credit (a_rwnd) must be >= 1500")
+	ErrChunkTypeNotInitAck              = errors.New("ChunkType is not of type INIT ACK")
+	ErrChunkNotLongEnoughForParams      = errors.New("chunk Value isn't long enough for mandatory parameters exp")
+	ErrChunkTypeInitAckFlagZero         = errors.New("ChunkType of type INIT ACK flags must be all 0")
+	ErrInitAckUnmarshalFailed           = errors.New("failed to unmarshal INIT body")
+	ErrInitCommonDataMarshalFailed      = errors.New("failed marshaling INIT common data")
+	ErrChunkTypeInitAckInitateTagZero   = errors.New("ChunkType of type INIT ACK InitiateTag must not be 0")
+	ErrInitAckInboundStreamRequestZero  = errors.New("INIT ACK inbound stream request must be > 0")
+	ErrInitAckOutboundStreamRequestZero = errors.New("INIT ACK outbound stream request must be > 0")
+	ErrInitAckAdvertisedReceiver1500    = errors.New("INIT ACK Advertised Receiver Window Credit (a_rwnd) must be >= 1500")
 )
 
 func (i *chunkInitAck) unmarshal(raw []byte) error {
@@ -42,20 +43,20 @@ func (i *chunkInitAck) unmarshal(raw []byte) error {
 	}
 
 	if i.typ != ctInitAck {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotInitAck, i.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotInitAck, i.typ.String())
 	} else if len(i.raw) < initChunkMinLength {
-		return fmt.Errorf("%w: %d actual: %d", errChunkNotLongEnoughForParams, initChunkMinLength, len(i.raw))
+		return fmt.Errorf("%w: %d actual: %d", ErrChunkNotLongEnoughForParams, initChunkMinLength, len(i.raw))
 	}
 
 	// The Chunk Flags field in INIT is reserved, and all bits in it should
 	// be set to 0 by the sender and ignored by the receiver.  The sequence
 	// of parameters within an INIT can be processed in any order.
 	if i.flags != 0 {
-		return errChunkTypeInitAckFlagZero
+		return ErrChunkTypeInitAckFlagZero
 	}
 
 	if err := i.chunkInitCommon.unmarshal(i.raw); err != nil {
-		return fmt.Errorf("%w: %v", errInitAckUnmarshalFailed, err)
+		return fmt.Errorf("%w: %v", ErrInitAckUnmarshalFailed, err)
 	}
 
 	return nil
@@ -64,7 +65,7 @@ func (i *chunkInitAck) unmarshal(raw []byte) error {
 func (i *chunkInitAck) marshal() ([]byte, error) {
 	initShared, err := i.chunkInitCommon.marshal()
 	if err != nil {
-		return nil, fmt.Errorf("%w: %v", errInitCommonDataMarshalFailed, err)
+		return nil, fmt.Errorf("%w: %v", ErrInitCommonDataMarshalFailed, err)
 	}
 
 	i.chunkHeader.typ = ctInitAck
@@ -87,7 +88,7 @@ func (i *chunkInitAck) check() (abort bool, err error) {
 	// purpose.
 	if i.initiateTag == 0 {
 		abort = true
-		return abort, errChunkTypeInitAckInitateTagZero
+		return abort, ErrChunkTypeInitAckInitateTagZero
 	}
 
 	// Defines the maximum number of streams the sender of this INIT ACK
@@ -102,7 +103,7 @@ func (i *chunkInitAck) check() (abort bool, err error) {
 	// destroy the association discarding its TCB.
 	if i.numInboundStreams == 0 {
 		abort = true
-		return abort, errInitAckInboundStreamRequestZero
+		return abort, ErrInitAckInboundStreamRequestZero
 	}
 
 	// Defines the number of outbound streams the sender of this INIT ACK
@@ -115,7 +116,7 @@ func (i *chunkInitAck) check() (abort bool, err error) {
 
 	if i.numOutboundStreams == 0 {
 		abort = true
-		return abort, errInitAckOutboundStreamRequestZero
+		return abort, ErrInitAckOutboundStreamRequestZero
 	}
 
 	// An SCTP receiver MUST be able to receive a minimum of 1500 bytes in
@@ -124,7 +125,7 @@ func (i *chunkInitAck) check() (abort bool, err error) {
 	// ACK.
 	if i.advertisedReceiverWindowCredit < 1500 {
 		abort = true
-		return abort, errInitAckAdvertisedReceiver1500
+		return abort, ErrInitAckAdvertisedReceiver1500
 	}
 
 	return false, nil
diff --git a/chunk_init_common.go b/chunk_init_common.go
index 14535ca..9730f3c 100644
--- a/chunk_init_common.go
+++ b/chunk_init_common.go
@@ -53,10 +53,11 @@ const (
 	initOptionalVarHeaderLength = 4
 )
 
+// Init chunk errors
 var (
-	errInitChunkParseParamTypeFailed = errors.New("failed to parse param type")
-	errInitChunkUnmarshalParam       = errors.New("failed unmarshalling param in Init Chunk")
-	errInitAckMarshalParam           = errors.New("unable to marshal parameter for INIT/INITACK")
+	ErrInitChunkParseParamTypeFailed = errors.New("failed to parse param type")
+	ErrInitChunkUnmarshalParam       = errors.New("failed unmarshalling param in Init Chunk")
+	ErrInitAckMarshalParam           = errors.New("unable to marshal parameter for INIT/INITACK")
 )
 
 func (i *chunkInitCommon) unmarshal(raw []byte) error {
@@ -89,11 +90,11 @@ func (i *chunkInitCommon) unmarshal(raw []byte) error {
 		if remaining > initOptionalVarHeaderLength {
 			pType, err := parseParamType(raw[offset:])
 			if err != nil {
-				return fmt.Errorf("%w: %v", errInitChunkParseParamTypeFailed, err)
+				return fmt.Errorf("%w: %v", ErrInitChunkParseParamTypeFailed, err)
 			}
 			p, err := buildParam(pType, raw[offset:])
 			if err != nil {
-				return fmt.Errorf("%w: %v", errInitChunkUnmarshalParam, err)
+				return fmt.Errorf("%w: %v", ErrInitChunkUnmarshalParam, err)
 			}
 			i.params = append(i.params, p)
 			padding := getPadding(p.length())
@@ -117,7 +118,7 @@ func (i *chunkInitCommon) marshal() ([]byte, error) {
 	for idx, p := range i.params {
 		pp, err := p.marshal()
 		if err != nil {
-			return nil, fmt.Errorf("%w: %v", errInitAckMarshalParam, err)
+			return nil, fmt.Errorf("%w: %v", ErrInitAckMarshalParam, err)
 		}
 
 		out = append(out, pp...)
diff --git a/chunk_payload_data.go b/chunk_payload_data.go
index eecc7c8..7a98fcb 100644
--- a/chunk_payload_data.go
+++ b/chunk_payload_data.go
@@ -97,7 +97,10 @@ const (
 	PayloadTypeWebRTCBinaryEmpty PayloadProtocolIdentifier = 57
 )
 
-var errChunkPayloadSmall = errors.New("packet is smaller than the header size")
+// Data chunk errors
+var (
+	ErrChunkPayloadSmall = errors.New("packet is smaller than the header size")
+)
 
 func (p PayloadProtocolIdentifier) String() string {
 	switch p {
@@ -127,7 +130,7 @@ func (p *chunkPayloadData) unmarshal(raw []byte) error {
 	p.endingFragment = p.flags&payloadDataEndingFragmentBitmask != 0
 
 	if len(raw) < payloadDataHeaderSize {
-		return errChunkPayloadSmall
+		return ErrChunkPayloadSmall
 	}
 	p.tsn = binary.BigEndian.Uint32(p.raw[0:])
 	p.streamIdentifier = binary.BigEndian.Uint16(p.raw[4:])
diff --git a/chunk_reconfig.go b/chunk_reconfig.go
index c827a40..8688b59 100644
--- a/chunk_reconfig.go
+++ b/chunk_reconfig.go
@@ -28,10 +28,11 @@ type chunkReconfig struct {
 	paramB param
 }
 
+// Reconfigure chunk errors
 var (
-	errChunkParseParamTypeFailed        = errors.New("failed to parse param type")
-	errChunkMarshalParamAReconfigFailed = errors.New("unable to marshal parameter A for reconfig")
-	errChunkMarshalParamBReconfigFailed = errors.New("unable to marshal parameter B for reconfig")
+	ErrChunkParseParamTypeFailed        = errors.New("failed to parse param type")
+	ErrChunkMarshalParamAReconfigFailed = errors.New("unable to marshal parameter A for reconfig")
+	ErrChunkMarshalParamBReconfigFailed = errors.New("unable to marshal parameter B for reconfig")
 )
 
 func (c *chunkReconfig) unmarshal(raw []byte) error {
@@ -40,7 +41,7 @@ func (c *chunkReconfig) unmarshal(raw []byte) error {
 	}
 	pType, err := parseParamType(c.raw)
 	if err != nil {
-		return fmt.Errorf("%w: %v", errChunkParseParamTypeFailed, err)
+		return fmt.Errorf("%w: %v", ErrChunkParseParamTypeFailed, err)
 	}
 	a, err := buildParam(pType, c.raw)
 	if err != nil {
@@ -53,7 +54,7 @@ func (c *chunkReconfig) unmarshal(raw []byte) error {
 	if len(c.raw) > offset {
 		pType, err := parseParamType(c.raw[offset:])
 		if err != nil {
-			return fmt.Errorf("%w: %v", errChunkParseParamTypeFailed, err)
+			return fmt.Errorf("%w: %v", ErrChunkParseParamTypeFailed, err)
 		}
 		b, err := buildParam(pType, c.raw[offset:])
 		if err != nil {
@@ -68,7 +69,7 @@ func (c *chunkReconfig) unmarshal(raw []byte) error {
 func (c *chunkReconfig) marshal() ([]byte, error) {
 	out, err := c.paramA.marshal()
 	if err != nil {
-		return nil, fmt.Errorf("%w: %v", errChunkMarshalParamAReconfigFailed, err)
+		return nil, fmt.Errorf("%w: %v", ErrChunkMarshalParamAReconfigFailed, err)
 	}
 	if c.paramB != nil {
 		// Pad param A
@@ -76,7 +77,7 @@ func (c *chunkReconfig) marshal() ([]byte, error) {
 
 		outB, err := c.paramB.marshal()
 		if err != nil {
-			return nil, fmt.Errorf("%w: %v", errChunkMarshalParamBReconfigFailed, err)
+			return nil, fmt.Errorf("%w: %v", ErrChunkMarshalParamBReconfigFailed, err)
 		}
 
 		out = append(out, outB...)
diff --git a/chunk_selective_ack.go b/chunk_selective_ack.go
index 00f83db..28223a9 100644
--- a/chunk_selective_ack.go
+++ b/chunk_selective_ack.go
@@ -46,10 +46,11 @@ type gapAckBlock struct {
 	end   uint16
 }
 
+// Selective ack chunk errors
 var (
-	errChunkTypeNotSack           = errors.New("ChunkType is not of type SACK")
-	errSackSizeNotLargeEnoughInfo = errors.New("SACK Chunk size is not large enough to contain header")
-	errSackSizeNotMatchPredicted  = errors.New("SACK Chunk size does not match predicted amount from header values")
+	ErrChunkTypeNotSack           = errors.New("ChunkType is not of type SACK")
+	ErrSackSizeNotLargeEnoughInfo = errors.New("SACK Chunk size is not large enough to contain header")
+	ErrSackSizeNotMatchPredicted  = errors.New("SACK Chunk size does not match predicted amount from header values")
 )
 
 // String makes gapAckBlock printable
@@ -75,11 +76,11 @@ func (s *chunkSelectiveAck) unmarshal(raw []byte) error {
 	}
 
 	if s.typ != ctSack {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotSack, s.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotSack, s.typ.String())
 	}
 
 	if len(s.raw) < selectiveAckHeaderSize {
-		return fmt.Errorf("%w: %v remaining, needs %v bytes", errSackSizeNotLargeEnoughInfo,
+		return fmt.Errorf("%w: %v remaining, needs %v bytes", ErrSackSizeNotLargeEnoughInfo,
 			len(s.raw), selectiveAckHeaderSize)
 	}
 
@@ -89,7 +90,7 @@ func (s *chunkSelectiveAck) unmarshal(raw []byte) error {
 	s.duplicateTSN = make([]uint32, binary.BigEndian.Uint16(s.raw[10:]))
 
 	if len(s.raw) != selectiveAckHeaderSize+(4*len(s.gapAckBlocks)+(4*len(s.duplicateTSN))) {
-		return errSackSizeNotMatchPredicted
+		return ErrSackSizeNotMatchPredicted
 	}
 
 	offset := selectiveAckHeaderSize
diff --git a/chunk_shutdown.go b/chunk_shutdown.go
index be0371a..bcd9fc1 100644
--- a/chunk_shutdown.go
+++ b/chunk_shutdown.go
@@ -26,9 +26,10 @@ const (
 	cumulativeTSNAckLength = 4
 )
 
+// Shutdown chunk errors
 var (
-	errInvalidChunkSize     = errors.New("invalid chunk size")
-	errChunkTypeNotShutdown = errors.New("ChunkType is not of type SHUTDOWN")
+	ErrInvalidChunkSize     = errors.New("invalid chunk size")
+	ErrChunkTypeNotShutdown = errors.New("ChunkType is not of type SHUTDOWN")
 )
 
 func (c *chunkShutdown) unmarshal(raw []byte) error {
@@ -37,11 +38,11 @@ func (c *chunkShutdown) unmarshal(raw []byte) error {
 	}
 
 	if c.typ != ctShutdown {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotShutdown, c.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotShutdown, c.typ.String())
 	}
 
 	if len(c.raw) != cumulativeTSNAckLength {
-		return errInvalidChunkSize
+		return ErrInvalidChunkSize
 	}
 
 	c.cumulativeTSNAck = binary.BigEndian.Uint32(c.raw[0:])
diff --git a/chunk_shutdown_ack.go b/chunk_shutdown_ack.go
index f575dbb..a8bb8d0 100644
--- a/chunk_shutdown_ack.go
+++ b/chunk_shutdown_ack.go
@@ -18,7 +18,10 @@ type chunkShutdownAck struct {
 	chunkHeader
 }
 
-var errChunkTypeNotShutdownAck = errors.New("ChunkType is not of type SHUTDOWN-ACK")
+// Shutdown ack chunk errors
+var (
+	ErrChunkTypeNotShutdownAck = errors.New("ChunkType is not of type SHUTDOWN-ACK")
+)
 
 func (c *chunkShutdownAck) unmarshal(raw []byte) error {
 	if err := c.chunkHeader.unmarshal(raw); err != nil {
@@ -26,7 +29,7 @@ func (c *chunkShutdownAck) unmarshal(raw []byte) error {
 	}
 
 	if c.typ != ctShutdownAck {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotShutdownAck, c.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotShutdownAck, c.typ.String())
 	}
 
 	return nil
diff --git a/chunk_shutdown_complete.go b/chunk_shutdown_complete.go
index 99883f3..4de045d 100644
--- a/chunk_shutdown_complete.go
+++ b/chunk_shutdown_complete.go
@@ -18,7 +18,10 @@ type chunkShutdownComplete struct {
 	chunkHeader
 }
 
-var errChunkTypeNotShutdownComplete = errors.New("ChunkType is not of type SHUTDOWN-COMPLETE")
+// Shutdown complete chunk errors
+var (
+	ErrChunkTypeNotShutdownComplete = errors.New("ChunkType is not of type SHUTDOWN-COMPLETE")
+)
 
 func (c *chunkShutdownComplete) unmarshal(raw []byte) error {
 	if err := c.chunkHeader.unmarshal(raw); err != nil {
@@ -26,7 +29,7 @@ func (c *chunkShutdownComplete) unmarshal(raw []byte) error {
 	}
 
 	if c.typ != ctShutdownComplete {
-		return fmt.Errorf("%w: actually is %s", errChunkTypeNotShutdownComplete, c.typ.String())
+		return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotShutdownComplete, c.typ.String())
 	}
 
 	return nil
diff --git a/chunkheader.go b/chunkheader.go
index be2a122..f6f0d71 100644
--- a/chunkheader.go
+++ b/chunkheader.go
@@ -33,15 +33,16 @@ const (
 	chunkHeaderSize = 4
 )
 
+// SCTP chunk header errors
 var (
-	errChunkHeaderTooSmall       = errors.New("raw is too small for a SCTP chunk")
-	errChunkHeaderNotEnoughSpace = errors.New("not enough data left in SCTP packet to satisfy requested length")
-	errChunkHeaderPaddingNonZero = errors.New("chunk padding is non-zero at offset")
+	ErrChunkHeaderTooSmall       = errors.New("raw is too small for a SCTP chunk")
+	ErrChunkHeaderNotEnoughSpace = errors.New("not enough data left in SCTP packet to satisfy requested length")
+	ErrChunkHeaderPaddingNonZero = errors.New("chunk padding is non-zero at offset")
 )
 
 func (c *chunkHeader) unmarshal(raw []byte) error {
 	if len(raw) < chunkHeaderSize {
-		return fmt.Errorf("%w: raw only %d bytes, %d is the minimum length", errChunkHeaderTooSmall, len(raw), chunkHeaderSize)
+		return fmt.Errorf("%w: raw only %d bytes, %d is the minimum length", ErrChunkHeaderTooSmall, len(raw), chunkHeaderSize)
 	}
 
 	c.typ = chunkType(raw[0])
@@ -53,7 +54,7 @@ func (c *chunkHeader) unmarshal(raw []byte) error {
 	lengthAfterValue := len(raw) - (chunkHeaderSize + valueLength)
 
 	if lengthAfterValue < 0 {
-		return fmt.Errorf("%w: remain %d req %d ", errChunkHeaderNotEnoughSpace, valueLength, len(raw)-chunkHeaderSize)
+		return fmt.Errorf("%w: remain %d req %d ", ErrChunkHeaderNotEnoughSpace, valueLength, len(raw)-chunkHeaderSize)
 	} else if lengthAfterValue < 4 {
 		// https://tools.ietf.org/html/rfc4960#section-3.2
 		// The Chunk Length field does not count any chunk padding.
@@ -67,7 +68,7 @@ func (c *chunkHeader) unmarshal(raw []byte) error {
 		for i := lengthAfterValue; i > 0; i-- {
 			paddingOffset := chunkHeaderSize + valueLength + (i - 1)
 			if raw[paddingOffset] != 0 {
-				return fmt.Errorf("%w: %d ", errChunkHeaderPaddingNonZero, paddingOffset)
+				return fmt.Errorf("%w: %d ", ErrChunkHeaderPaddingNonZero, paddingOffset)
 			}
 		}
 	}
diff --git a/error_cause.go b/error_cause.go
index a511c13..9e5e68d 100644
--- a/error_cause.go
+++ b/error_cause.go
@@ -18,7 +18,10 @@ type errorCause interface {
 	errorCauseCode() errorCauseCode
 }
 
-var errBuildErrorCaseHandle = errors.New("BuildErrorCause does not handle")
+// Error and abort chunk errors
+var (
+	ErrBuildErrorCaseHandle = errors.New("BuildErrorCause does not handle")
+)
 
 // buildErrorCause delegates the building of a error cause from raw bytes to the correct structure
 func buildErrorCause(raw []byte) (errorCause, error) {
@@ -35,7 +38,7 @@ func buildErrorCause(raw []byte) (errorCause, error) {
 	case userInitiatedAbort:
 		e = &errorCauseUserInitiatedAbort{}
 	default:
-		return nil, fmt.Errorf("%w: %s", errBuildErrorCaseHandle, c.String())
+		return nil, fmt.Errorf("%w: %s", ErrBuildErrorCaseHandle, c.String())
 	}
 
 	if err := e.unmarshal(raw); err != nil {
diff --git a/error_cause_protocol_violation.go b/error_cause_protocol_violation.go
index 3379ea2..b613685 100644
--- a/error_cause_protocol_violation.go
+++ b/error_cause_protocol_violation.go
@@ -27,7 +27,10 @@ type errorCauseProtocolViolation struct {
 	additionalInformation []byte
 }
 
-var errProtocolViolationUnmarshal = errors.New("unable to unmarshal Protocol Violation error")
+// Abort chunk errors
+var (
+	ErrProtocolViolationUnmarshal = errors.New("unable to unmarshal Protocol Violation error")
+)
 
 func (e *errorCauseProtocolViolation) marshal() ([]byte, error) {
 	e.raw = e.additionalInformation
@@ -37,7 +40,7 @@ func (e *errorCauseProtocolViolation) marshal() ([]byte, error) {
 func (e *errorCauseProtocolViolation) unmarshal(raw []byte) error {
 	err := e.errorCauseHeader.unmarshal(raw)
 	if err != nil {
-		return fmt.Errorf("%w: %v", errProtocolViolationUnmarshal, err)
+		return fmt.Errorf("%w: %v", ErrProtocolViolationUnmarshal, err)
 	}
 
 	e.additionalInformation = e.raw
diff --git a/packet.go b/packet.go
index f1765ad..1c17e69 100644
--- a/packet.go
+++ b/packet.go
@@ -59,16 +59,17 @@ const (
 	packetHeaderSize = 12
 )
 
+// SCTP packet errors
 var (
-	errPacketRawTooSmall           = errors.New("raw is smaller than the minimum length for a SCTP packet")
-	errParseSCTPChunkNotEnoughData = errors.New("unable to parse SCTP chunk, not enough data for complete header")
-	errUnmarshalUnknownChunkType   = errors.New("failed to unmarshal, contains unknown chunk type")
-	errChecksumMismatch            = errors.New("checksum mismatch theirs")
+	ErrPacketRawTooSmall           = errors.New("raw is smaller than the minimum length for a SCTP packet")
+	ErrParseSCTPChunkNotEnoughData = errors.New("unable to parse SCTP chunk, not enough data for complete header")
+	ErrUnmarshalUnknownChunkType   = errors.New("failed to unmarshal, contains unknown chunk type")
+	ErrChecksumMismatch            = errors.New("checksum mismatch theirs")
 )
 
 func (p *packet) unmarshal(raw []byte) error {
 	if len(raw) < packetHeaderSize {
-		return fmt.Errorf("%w: raw only %d bytes, %d is the minimum length", errPacketRawTooSmall, len(raw), packetHeaderSize)
+		return fmt.Errorf("%w: raw only %d bytes, %d is the minimum length", ErrPacketRawTooSmall, len(raw), packetHeaderSize)
 	}
 
 	p.sourcePort = binary.BigEndian.Uint16(raw[0:])
@@ -81,7 +82,7 @@ func (p *packet) unmarshal(raw []byte) error {
 		if offset == len(raw) {
 			break
 		} else if offset+chunkHeaderSize > len(raw) {
-			return fmt.Errorf("%w: offset %d remaining %d", errParseSCTPChunkNotEnoughData, offset, len(raw))
+			return fmt.Errorf("%w: offset %d remaining %d", ErrParseSCTPChunkNotEnoughData, offset, len(raw))
 		}
 
 		var c chunk
@@ -115,7 +116,7 @@ func (p *packet) unmarshal(raw []byte) error {
 		case ctShutdownComplete:
 			c = &chunkShutdownComplete{}
 		default:
-			return fmt.Errorf("%w: %s", errUnmarshalUnknownChunkType, chunkType(raw[offset]).String())
+			return fmt.Errorf("%w: %s", ErrUnmarshalUnknownChunkType, chunkType(raw[offset]).String())
 		}
 
 		if err := c.unmarshal(raw[offset:]); err != nil {
@@ -129,7 +130,7 @@ func (p *packet) unmarshal(raw []byte) error {
 	theirChecksum := binary.LittleEndian.Uint32(raw[8:])
 	ourChecksum := generatePacketChecksum(raw)
 	if theirChecksum != ourChecksum {
-		return fmt.Errorf("%w: %d ours: %d", errChecksumMismatch, theirChecksum, ourChecksum)
+		return fmt.Errorf("%w: %d ours: %d", ErrChecksumMismatch, theirChecksum, ourChecksum)
 	}
 	return nil
 }
diff --git a/param.go b/param.go
index b7887c5..a239353 100644
--- a/param.go
+++ b/param.go
@@ -10,7 +10,8 @@ type param interface {
 	length() int
 }
 
-var errParamTypeUnhandled = errors.New("unhandled ParamType")
+// ErrParamTypeUnhandled is returned if unknown parameter type is specified.
+var ErrParamTypeUnhandled = errors.New("unhandled ParamType")
 
 func buildParam(t paramType, rawParam []byte) (param, error) {
 	switch t {
@@ -35,6 +36,6 @@ func buildParam(t paramType, rawParam []byte) (param, error) {
 	case reconfigResp:
 		return (&paramReconfigResponse{}).unmarshal(rawParam)
 	default:
-		return nil, fmt.Errorf("%w: %v", errParamTypeUnhandled, t)
+		return nil, fmt.Errorf("%w: %v", ErrParamTypeUnhandled, t)
 	}
 }
diff --git a/param_outgoing_reset_request.go b/param_outgoing_reset_request.go
index ceae178..8ec0bf6 100644
--- a/param_outgoing_reset_request.go
+++ b/param_outgoing_reset_request.go
@@ -52,7 +52,10 @@ type paramOutgoingResetRequest struct {
 	streamIdentifiers []uint16
 }
 
-var errSSNResetRequestParamTooShort = errors.New("outgoing SSN reset request parameter too short")
+// Outgoing reset request parameter errors
+var (
+	ErrSSNResetRequestParamTooShort = errors.New("outgoing SSN reset request parameter too short")
+)
 
 func (r *paramOutgoingResetRequest) marshal() ([]byte, error) {
 	r.typ = outSSNResetReq
@@ -72,7 +75,7 @@ func (r *paramOutgoingResetRequest) unmarshal(raw []byte) (param, error) {
 		return nil, err
 	}
 	if len(r.raw) < paramOutgoingResetRequestStreamIdentifiersOffset {
-		return nil, errSSNResetRequestParamTooShort
+		return nil, ErrSSNResetRequestParamTooShort
 	}
 	r.reconfigRequestSequenceNumber = binary.BigEndian.Uint32(r.raw)
 	r.reconfigResponseSequenceNumber = binary.BigEndian.Uint32(r.raw[4:])
diff --git a/param_reconfig_response.go b/param_reconfig_response.go
index d9eab55..e3bfab5 100644
--- a/param_reconfig_response.go
+++ b/param_reconfig_response.go
@@ -45,7 +45,10 @@ const (
 	reconfigResultInProgress                    reconfigResult = 6
 )
 
-var errReconfigRespParamTooShort = errors.New("reconfig response parameter too short")
+// Reconfiguration response errors
+var (
+	ErrReconfigRespParamTooShort = errors.New("reconfig response parameter too short")
+)
 
 func (t reconfigResult) String() string {
 	switch t {
@@ -83,7 +86,7 @@ func (r *paramReconfigResponse) unmarshal(raw []byte) (param, error) {
 		return nil, err
 	}
 	if len(r.raw) < 8 {
-		return nil, errReconfigRespParamTooShort
+		return nil, ErrReconfigRespParamTooShort
 	}
 	r.reconfigResponseSequenceNumber = binary.BigEndian.Uint32(r.raw)
 	r.result = reconfigResult(binary.BigEndian.Uint32(r.raw[4:]))
diff --git a/param_requested_hmac_algorithm.go b/param_requested_hmac_algorithm.go
index 895f3d7..d546af8 100644
--- a/param_requested_hmac_algorithm.go
+++ b/param_requested_hmac_algorithm.go
@@ -15,7 +15,8 @@ const (
 	hmacSHA256 hmacAlgorithm = 3
 )
 
-var errInvalidAlgorithmType = errors.New("invalid algorithm type")
+// ErrInvalidAlgorithmType is returned if unknown auth algorithm is specified.
+var ErrInvalidAlgorithmType = errors.New("invalid algorithm type")
 
 func (c hmacAlgorithm) String() string {
 	switch c {
@@ -64,7 +65,7 @@ func (r *paramRequestedHMACAlgorithm) unmarshal(raw []byte) (param, error) {
 		case hmacSHA256:
 			r.availableAlgorithms = append(r.availableAlgorithms, a)
 		default:
-			return nil, fmt.Errorf("%w: %v", errInvalidAlgorithmType, a)
+			return nil, fmt.Errorf("%w: %v", ErrInvalidAlgorithmType, a)
 		}
 
 		i += 2
diff --git a/paramheader.go b/paramheader.go
index f814d46..2f4a464 100644
--- a/paramheader.go
+++ b/paramheader.go
@@ -17,11 +17,12 @@ const (
 	paramHeaderLength = 4
 )
 
+// Parameter header parse errors
 var (
-	errParamHeaderTooShort                  = errors.New("param header too short")
-	errParamHeaderSelfReportedLengthShorter = errors.New("param self reported length is shorter than header length")
-	errParamHeaderSelfReportedLengthLonger  = errors.New("param self reported length is longer than header length")
-	errParamHeaderParseFailed               = errors.New("failed to parse param type")
+	ErrParamHeaderTooShort                  = errors.New("param header too short")
+	ErrParamHeaderSelfReportedLengthShorter = errors.New("param self reported length is shorter than header length")
+	ErrParamHeaderSelfReportedLengthLonger  = errors.New("param self reported length is longer than header length")
+	ErrParamHeaderParseFailed               = errors.New("failed to parse param type")
 )
 
 func (p *paramHeader) marshal() ([]byte, error) {
@@ -37,20 +38,20 @@ func (p *paramHeader) marshal() ([]byte, error) {
 
 func (p *paramHeader) unmarshal(raw []byte) error {
 	if len(raw) < paramHeaderLength {
-		return errParamHeaderTooShort
+		return ErrParamHeaderTooShort
 	}
 
 	paramLengthPlusHeader := binary.BigEndian.Uint16(raw[2:])
 	if int(paramLengthPlusHeader) < paramHeaderLength {
-		return fmt.Errorf("%w: param self reported length (%d) shorter than header length (%d)", errParamHeaderSelfReportedLengthShorter, int(paramLengthPlusHeader), paramHeaderLength)
+		return fmt.Errorf("%w: param self reported length (%d) shorter than header length (%d)", ErrParamHeaderSelfReportedLengthShorter, int(paramLengthPlusHeader), paramHeaderLength)
 	}
 	if len(raw) < int(paramLengthPlusHeader) {
-		return fmt.Errorf("%w: param length (%d) shorter than its self reported length (%d)", errParamHeaderSelfReportedLengthLonger, len(raw), int(paramLengthPlusHeader))
+		return fmt.Errorf("%w: param length (%d) shorter than its self reported length (%d)", ErrParamHeaderSelfReportedLengthLonger, len(raw), int(paramLengthPlusHeader))
 	}
 
 	typ, err := parseParamType(raw[0:])
 	if err != nil {
-		return fmt.Errorf("%w: %v", errParamHeaderParseFailed, err)
+		return fmt.Errorf("%w: %v", ErrParamHeaderParseFailed, err)
 	}
 	p.typ = typ
 	p.raw = raw[paramHeaderLength:paramLengthPlusHeader]
diff --git a/paramtype.go b/paramtype.go
index 9fe2cf1..2db73dd 100644
--- a/paramtype.go
+++ b/paramtype.go
@@ -39,11 +39,14 @@ const (
 	adaptLayerInd      paramType = 49158 // Adaptation Layer Indication (0xC006)	[RFC5061]
 )
 
-var errParamPacketTooShort = errors.New("packet to short")
+// Parameter packet errors
+var (
+	ErrParamPacketTooShort = errors.New("packet to short")
+)
 
 func parseParamType(raw []byte) (paramType, error) {
 	if len(raw) < 2 {
-		return paramType(0), errParamPacketTooShort
+		return paramType(0), ErrParamPacketTooShort
 	}
 	return paramType(binary.BigEndian.Uint16(raw)), nil
 }
diff --git a/pending_queue.go b/pending_queue.go
index a6e1a7a..8082cf5 100644
--- a/pending_queue.go
+++ b/pending_queue.go
@@ -48,10 +48,11 @@ type pendingQueue struct {
 	unorderedIsSelected bool
 }
 
+// Pending queue errors
 var (
-	errUnexpectedChuckPoppedUnordered = errors.New("unexpected chunk popped (unordered)")
-	errUnexpectedChuckPoppedOrdered   = errors.New("unexpected chunk popped (ordered)")
-	errUnexpectedQState               = errors.New("unexpected q state (should've been selected)")
+	ErrUnexpectedChuckPoppedUnordered = errors.New("unexpected chunk popped (unordered)")
+	ErrUnexpectedChuckPoppedOrdered   = errors.New("unexpected chunk popped (ordered)")
+	ErrUnexpectedQState               = errors.New("unexpected q state (should've been selected)")
 )
 
 func newPendingQueue() *pendingQueue {
@@ -90,12 +91,12 @@ func (q *pendingQueue) pop(c *chunkPayloadData) error {
 		if q.unorderedIsSelected {
 			popped = q.unorderedQueue.pop()
 			if popped != c {
-				return errUnexpectedChuckPoppedUnordered
+				return ErrUnexpectedChuckPoppedUnordered
 			}
 		} else {
 			popped = q.orderedQueue.pop()
 			if popped != c {
-				return errUnexpectedChuckPoppedOrdered
+				return ErrUnexpectedChuckPoppedOrdered
 			}
 		}
 		if popped.endingFragment {
@@ -103,12 +104,12 @@ func (q *pendingQueue) pop(c *chunkPayloadData) error {
 		}
 	} else {
 		if !c.beginningFragment {
-			return errUnexpectedQState
+			return ErrUnexpectedQState
 		}
 		if c.unordered {
 			popped := q.unorderedQueue.pop()
 			if popped != c {
-				return errUnexpectedChuckPoppedUnordered
+				return ErrUnexpectedChuckPoppedUnordered
 			}
 			if !popped.endingFragment {
 				q.selected = true
@@ -117,7 +118,7 @@ func (q *pendingQueue) pop(c *chunkPayloadData) error {
 		} else {
 			popped := q.orderedQueue.pop()
 			if popped != c {
-				return errUnexpectedChuckPoppedOrdered
+				return ErrUnexpectedChuckPoppedOrdered
 			}
 			if !popped.endingFragment {
 				q.selected = true
diff --git a/stream.go b/stream.go
index fd2c5fc..43038ee 100644
--- a/stream.go
+++ b/stream.go
@@ -45,10 +45,11 @@ func (ss StreamState) String() string {
 	return "unknown"
 }
 
+// SCTP stream errors
 var (
-	errOutboundPacketTooLarge = errors.New("outbound packet larger than maximum message size")
-	errStreamClosed           = errors.New("stream closed")
-	errReadDeadlineExceeded   = fmt.Errorf("read deadline exceeded: %w", os.ErrDeadlineExceeded)
+	ErrOutboundPacketTooLarge = errors.New("outbound packet larger than maximum message size")
+	ErrStreamClosed           = errors.New("stream closed")
+	ErrReadDeadlineExceeded   = fmt.Errorf("read deadline exceeded: %w", os.ErrDeadlineExceeded)
 )
 
 // Stream represents an SCTP stream
@@ -155,7 +156,7 @@ func (s *Stream) SetReadDeadline(deadline time.Time) error {
 	}
 
 	if s.readErr != nil {
-		if !errors.Is(s.readErr, errReadDeadlineExceeded) {
+		if !errors.Is(s.readErr, ErrReadDeadlineExceeded) {
 			return nil
 		}
 		s.readErr = nil
@@ -173,7 +174,7 @@ func (s *Stream) SetReadDeadline(deadline time.Time) error {
 			case <-t.C:
 				s.lock.Lock()
 				if s.readErr == nil {
-					s.readErr = errReadDeadlineExceeded
+					s.readErr = ErrReadDeadlineExceeded
 				}
 				s.readTimeoutCancel = nil
 				s.lock.Unlock()
@@ -257,18 +258,18 @@ func (s *Stream) Write(p []byte) (n int, err error) {
 func (s *Stream) WriteSCTP(p []byte, ppi PayloadProtocolIdentifier) (int, error) {
 	maxMessageSize := s.association.MaxMessageSize()
 	if len(p) > int(maxMessageSize) {
-		return 0, fmt.Errorf("%w: %v", errOutboundPacketTooLarge, math.MaxUint16)
+		return 0, fmt.Errorf("%w: %v", ErrOutboundPacketTooLarge, math.MaxUint16)
 	}
 
 	if s.State() != StreamStateOpen {
-		return 0, errStreamClosed
+		return 0, ErrStreamClosed
 	}
 
 	chunks := s.packetize(p, ppi)
 	n := len(p)
 	err := s.association.sendPayloadData(chunks)
 	if err != nil {
-		return n, errStreamClosed
+		return n, ErrStreamClosed
 	}
 	return n, nil
 }


Test patch:
diff --git a/chunk_test.go b/chunk_test.go
index 6708862..349b21a 100644
--- a/chunk_test.go
+++ b/chunk_test.go
@@ -102,9 +102,9 @@ func TestInitMarshalUnmarshal(t *testing.T) {
 	initAck.numInboundStreams = 1
 	initAck.initiateTag = 123
 	initAck.advertisedReceiverWindowCredit = 1024
-	cookie, errRand := newRandomStateCookie()
-	if errRand != nil {
-		t.Fatalf("Failed to generate random state cookie: %v", errRand)
+	cookie, ErrRand := newRandomStateCookie()
+	if ErrRand != nil {
+		t.Fatalf("Failed to generate random state cookie: %v", ErrRand)
 	}
 	initAck.params = []param{cookie}
 
diff --git a/vnet_test.go b/vnet_test.go
index 996f495..058bc24 100644
--- a/vnet_test.go
+++ b/vnet_test.go
@@ -542,7 +542,7 @@ func TestStreamClose(t *testing.T) {
 
 		_, err = stream.Write([]byte{1})
 
-		assert.Equal(t, err, errStreamClosed, "after closed should not allow write")
+		assert.Equal(t, err, ErrStreamClosed, "after closed should not allow write")
 		// Check if RECONFIG was actually dropped
 		assert.Equal(t, 0, venv.numToDropReconfig, "should be zero")