diff options
| author | Shulhan <ms@kilabit.info> | 2019-03-10 19:55:53 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2019-03-10 19:55:53 +0700 |
| commit | fea9c7bbd87d93eb2ccd379769a0fae7b8873f9c (patch) | |
| tree | 91bafc55dd3cddc6b1cfaf85f5572ff2c19df268 /lib/websocket | |
| parent | 2a3bd1898256bfa878485f2d61a193057499f656 (diff) | |
| download | pakakeh.go-fea9c7bbd87d93eb2ccd379769a0fae7b8873f9c.tar.xz | |
websocket: close connection on unnegotiated reserved bits on server
When server received frame with reserved bits set, and no extension
has been negotitated or provided by server to allow its, server MUST
close the connection per RFC 6455, section 5.2.
Diffstat (limited to 'lib/websocket')
| -rw-r--r-- | lib/websocket/frame.go | 8 | ||||
| -rw-r--r-- | lib/websocket/server.go | 34 |
2 files changed, 42 insertions, 0 deletions
diff --git a/lib/websocket/frame.go b/lib/websocket/frame.go index dee4ee1b..8cb8149e 100644 --- a/lib/websocket/frame.go +++ b/lib/websocket/frame.go @@ -19,6 +19,11 @@ type Frame struct { // The first fragment MAY also be the final fragment. fin byte + // rsv1, rsv2, and rsv3 is reserved bits in frame. + rsv1 byte + rsv2 byte + rsv3 byte + // opcode (4 bits) defines the interpretation of the "Payload data". // If an unknown opcode is received, the receiving endpoint MUST _Fail // the WebSocket Connection_. The following values are defined. @@ -209,6 +214,9 @@ func frameUnpack(in []byte) (f *Frame, rest []byte) { x := 0 f.fin = in[x] & frameIsFinished + f.rsv1 = in[x] & 0x40 + f.rsv2 = in[x] & 0x20 + f.rsv3 = in[x] & 0x10 f.opcode = opcode(in[x] & 0x0F) x++ if x >= len(in) { diff --git a/lib/websocket/server.go b/lib/websocket/server.go index 7eb664c6..1ed125d6 100644 --- a/lib/websocket/server.go +++ b/lib/websocket/server.go @@ -72,6 +72,10 @@ type Server struct { // handlePong callback that will be called after receiving control // PONG frame from client. Default is nil, used only for testing. handlePong HandlerFrameFn + + allowRsv1 bool + allowRsv2 bool + allowRsv3 bool } // @@ -93,6 +97,21 @@ func NewServer(port int) (serv *Server, err error) { return } +// +// AllowReservedBits allow receiving frame with RSV1, RSV2, or RSV3 bit set. +// Calling this function means server has negotiated the extension that use +// the reserved bits through handshake with client using HandleAuth. +// +// If a nonzero value is received in reserved bits and none of the negotiated +// extensions defines the meaning of such a nonzero value, server will close +// the connection (RFC 6455, section 5.2). +// +func (serv *Server) AllowReservedBits(one, two, three bool) { + serv.allowRsv1 = one + serv.allowRsv2 = two + serv.allowRsv3 = three +} + func (serv *Server) createEpoolRead() (err error) { serv.epollRead, err = unix.EpollCreate1(0) if err != nil { @@ -525,6 +544,21 @@ func (serv *Server) reader() { isClosing = true break } + if frame.rsv1 > 0 && !serv.allowRsv1 { + serv.handleBadRequest(conn) + isClosing = true + break + } + if frame.rsv2 > 0 && !serv.allowRsv2 { + serv.handleBadRequest(conn) + isClosing = true + break + } + if frame.rsv3 > 0 && !serv.allowRsv3 { + serv.handleBadRequest(conn) + isClosing = true + break + } switch frame.opcode { case opcodeCont, opcodeText, opcodeBin: |
