Esempio n. 1
0
// handleWindowUpdate performs the processing of WINDOW_UPDATE frames.
func (c *Conn) handleWindowUpdate(frame *frames.WINDOW_UPDATE) {
	sid := frame.StreamID

	if c.criticalCheck(!sid.Valid(), sid, "Received WINDOW_UPDATE with excessive Stream ID %d", sid) {
		return
	}

	delta := frame.DeltaWindowSize
	bad := delta > common.MAX_DELTA_WINDOW_SIZE || delta < 1
	if c.criticalCheck(bad, sid, "Received WINDOW_UPDATE with invalid delta window size %d", delta) {
		return
	}

	// Handle connection-level flow control.
	if sid.Zero() && c.Subversion > 0 {
		c.connectionWindowLock.Lock()
		defer c.connectionWindowLock.Unlock()

		if int64(delta)+c.connectionWindowSize > common.MAX_TRANSFER_WINDOW_SIZE {
			goaway := new(frames.GOAWAY)
			if c.server != nil {
				c.lastRequestStreamIDLock.Lock()
				goaway.LastGoodStreamID = c.lastRequestStreamID
				c.lastRequestStreamIDLock.Unlock()
			} else {
				c.lastPushStreamIDLock.Lock()
				goaway.LastGoodStreamID = c.lastPushStreamID
				c.lastPushStreamIDLock.Unlock()
			}
			goaway.Status = common.GOAWAY_FLOW_CONTROL_ERROR
			c.output[0] <- goaway
			return
		}
		c.connectionWindowSize += int64(delta)
		return
	}

	// Check stream is open.
	c.streamsLock.Lock()
	stream := c.streams[sid]
	c.streamsLock.Unlock()
	if stream == nil || stream.State().ClosedHere() {
		// This is almost certainly benign
		return
	}

	// Stream ID is fine.
	stream.ReceiveFrame(frame)
}
Esempio n. 2
0
func (c *Conn) _GOAWAY(status common.StatusCode) {
	goaway := new(frames.GOAWAY)
	goaway.Status = status
	c.output[0] <- goaway
	c.Close()
}